sgykfjsm.github.com

DynamoDBをEMRで扱うときに気をつけること

実際に検証したわけではないが、経験的にDynamoDBをEMRで扱うときには以下の点に気を付ける必要がある。

DynamoDBからフェッチするカラムは後続の処理で必要とする最低限にとどめておく。

DynamoDBは1度のスキャンで読み取れるのは1.5KB(整合性を保証したいなら1KB)なので、カラムに無駄があるとスループットが悪くなる。ブログコンテンツのように1カラムで1KBを超えるような場合は相当スループットが落ちる。何となく後で必要になるだろうから、という理由で使わないカラムをフェッチするのは無駄。

DynamoDBを直接参照する処理は極力避ける。

DynamoDBから必要な行をフィルタリングしてEMRのローカルに保持してから集計処理などを行うべきである。理由は上記とほぼ同じ。

DynamoDBのRead Capacity Unitはキャップの上限を引き上げるが、スループットを保証しない。

このへんが謎。400に引き上げても200ぐらいで頭打ちになる。

キー(id_hash)を分散させること

DynamoDBにかぎらずNoSQL系DB全てに言えることだけど、キーが分散していないと処理が遅い。

EMRからDynamoDBを直接参照するぐらいなら、一度S3にエクスポートしてからS3のファイルを外部表にしてEMRで処理したほうが早く、コスト安になりやすい。

処理の内容によるだろうけど、DynamoDBは新しいレコードほど早く取り出せるような気がする(未検証)ので、日次などで定期的にS3にエクスポートしてEMRで処理したほうが良い。件数にもよるが、キーが分散していない1ヶ月前のDynamoDBのレコードをとりだすのに相当時間がかかる(10時間ぐらい)こともある。

2013/09/27 05:18:03 追記

DynamoDBは新しいレコードほど早く取り出せるような気がする(未検証)

これは全くの大嘘。実際にログを見てみるとちゃんと古いものからスキャンしてた。だから何って話なんだけど。

可能であれば、id_rangeを指定すること。

id_hashが分散してなくてもid_rangeが指定できればなんとかパフォーマンスを向上させる余地はある。


この辺の事柄に気をつけても遅いときは本当に遅い。DynamoDBはid_hashやid_rangeで一本釣りできるような場合は有効だけど、ログの蓄積とか集計用途には向いてない気がする。