今回も前回に引き続き
GAE MapReduce。
前回
GAEと
GCSで連携してMapReduceを実行してみたが、
今回は性能評価として、
以下を実施してみた。
実施内容
10MB(MegaByte)のテキストファイル※に対してWordCountを行い性能評価を行った。
※妥当かどうかは微妙です。。決してビッグデータとは言えない。。
●評価環境
【Google App Engine】
Runtime:Python
SystemStatus:Normal
Latency:Normal
●計測で使用したWordCountプログラム
前回のエントリで紹介した
GCS上のファイルを読み込むInputReaderと
中間ファイル、出力ファイルを
GCS上に出力するMapreducePipelineを使用した。
※バグがあったので修正したものを
コミットしました。
計測結果
【WordCount処理時間】
上記結果から見て取れるようにshard数4〜8で処理時間は大幅に減少している。
また、shard数16から32は収束状態となった。
この結果からファイルサイズ10MB程度であれば、shard数8から16程度までが
妥当な数となり、8以下だと処理時間が増加し、16以上だとオーバーワーク気味に
なってしまう。
(pipeline処理が行うDatastoreへのRead/Writeオペレーションがshard数に比例して増加する為。shard数32以上で実施したらあっという間にOverQuotaになった。)
【Instance数】
上記結果から見て取れるようにshard数4〜16まではshard数に比例して
スケールしている事がわかる。
また、shard数
16〜32はほぼ収束状態となった。
【Memory Usage(MB)】
これはあまり参考にならなかった。。
【shard数に於けるMap処理】
1Task(約15sec)で処理するMap数についてまとめてみた。
■shard数4
・Overview
Elapsed time: 00:04:46
・Counters
io-write-bytes: 30277632 (105865.85/sec avg.)
io-write-msec: 8140 (28.46/sec avg.)
mapper-calls: 93762 (327.84/sec avg.)
mapper-walltime-ms: 565100 (1975.87/sec avg.)
(平均処理数:2391Map処理/Task)
■shard数8
・Overview
Elapsed time: 00:03:53
・Counters
io-write-bytes: 30474240 (130790.73/sec avg.)
io-write-msec: 6602 (28.33/sec avg.)
mapper-calls: 93762 (402.41/sec avg.)
mapper-walltime-ms: 591540 (2538.8/sec avg.)
(平均処理数:2256
Map処理/Task)
■shard数16
Overview
Elapsed time: 00:01:55
Counters
io-write-bytes: 30408704 (264423.51/sec avg.)
io-write-msec: 4249 (36.95/sec avg.)
mapper-calls: 93762 (815.32/sec avg.)
mapper-walltime-ms: 667741 (5806.44/sec avg.)
(平均処理数:2000Map処理/Task)
■shard数32
Overview
Elapsed time: 00:01:55
Counters
io-write-bytes: 30539776 (265563.27/sec avg.)
io-write-msec: 5755 (50.04/sec avg.)
mapper-calls: 93762 (815.32/sec avg.)
mapper-walltime-ms: 712984 (6199.86/sec avg.)
(平均処理数:1706Map処理/Task)
上記のとおり
mapper-callsを見る限り、shard数に応じて1秒間に処理するMap数は
増加しているように見える。
しかし、shard数によって1Task(1MapperTaskが15秒間に行うMap処理数)
のMap処理の処理数にあまり変化がないようだ
。
よってshard数によってGCSの読み書きレイテンシに影響はなく、
1Taskだいたい決まった数のMap処理を行う事ができる。
すなわちMap処理に関してだが、純粋にshard数に応じて、処理数が
比例するであろうと分かる結果であった。
※shard数32だけ例外だが、10MB程度だと1Mapperで数Taskほどしか
動かなかったので、妥当な結果が得られなかったためであろう。。(^^;)
おまけ
GCS連携版の
appengine-mapreduce2GCSと
appengine-mapreduceのBlobLineInputReaderを使用したもので、WordCount対決を行ってみた。
・WordCount処理対象
10MB(MegaByte)のテキストファイルをshard数16でWordCount
●結果
【WordCount処理時間】
・
appengine-mapreduce: 00:09:53.225
・appengine-mapreduce2GCS: 00:07:42.04
【Instance数】
・
appengine-mapreduce:最大30Instances
・appengine-mapreduce2GCS:最大24Instances
【Map処理】
・
appengine-mapreduce:
Overview
Elapsed time: 00:02:23
Counters
io-write-bytes: 30900224 (216085.48/sec avg.)
io-write-msec: 9142 (63.93/sec avg.)
mapper-calls: 93762 (655.68/sec avg.)
mapper-walltime-ms: 822627 (5752.64/sec avg.)
(平均処理数:1762
Map処理/Task)
・appengine-mapreduce2GCS:
Overview
Elapsed time: 00:01:44
Counters
io-write-bytes: 30277632 (291131.08/sec avg.)
io-write-msec: 3940 (37.88/sec avg.)
mapper-calls: 93762 (901.56/sec avg.)
mapper-walltime-ms: 662981 (6374.82/sec avg.)
(平均処理数:2012
Map処理/Task)
なんと!
GCS連携しているMapReduce処理のほうが早いという結果になった。
(Outputが正しいか検証したが、両者とも問題なかった。)
上記から見て取れるようにio-write-bytesに関して
GCSの方が、
高速であることが分かる。
(ただし、
GCSのほうはバケットに溜まったファイル群をリフレッシュしていた。
これが要因だとすると、不要なファイルは出来るだけ消しておくほうが良い?)
【まとめ】
今回は10MBというビッグデータとは決して言えないファイルを対象とした
検証であったので、妥当とは言えないかもしれない。
ただ、
GAEで手軽に並列処理を行えるというのはとても画期的で、
有用であると考えられる。(中規模のデータであれば十分)
今後はさらに発展させたMapReduceのアプリケーションをGAEで
作っていけたらと考えてる。
また、この計測結果も更新していこうかな。