SyntaxHighlighter

2012年7月29日日曜日

GAE Python urlfetchサービスを用いたテストについて


今回は、GAEでアプリケーションを開発する際のTipsを紹介。

・目的

GAE Pythonでurlfetchサービスを用いて通信で外部のコンテンツを取得する
処理のテストを行う場合、
外部への接続が切断されている、または外部のデータが変更された等で
テストが失敗するという事態が起こる事を避ける為、
実際の通信はせずにローカルのコンテンツ(ファイルなど)を使用してレスポンス
する。

・方法

GAEでは各種サービスをRPC経由で呼び出している。
開発環境では、RPCをフックしているstubを使用して実際の通信を行う処理を
行っている。
今回はそのstubの実装を変更し、レスポンスを独自に組み立てて返却する。

下記がコード


テストで使い回しが効くようにベースクラスとして作成した。
まず、apiproxy_stub_mapに各種サービスの独自に実装したstubを設定する。
今回はurlfetchなので、サービス名は"urlfetch"とする。
設定したstubクラスには_Dynamic_Fetchというメソッドが実装されているが、
RPCが実行されると使われるAPIProxyStub#MakeSyncCallで動的呼び出しが
行われているメソッドである。
このメソッドをオーバーライドし、独自のレスポンスを組みたてて返却する。
このようにモックを使用したテストを行いたい場合は、どのサービスでも
応用が効くはず。お試しあれ。

2012年7月16日月曜日

GoogleAppEngine MapReduceとGoogleCloudStorageを連携させてみた(2)

今回も前回に引き続きGAE MapReduce
前回GAEGCSで連携して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.)

(平均処理数:2256Map処理/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ほどしか
動かなかったので、妥当な結果が得られなかったためであろう。。(^^;)

おまけ

appengine-mapreduce VS appengine-mapreduce2GCS 



GCS連携版のappengine-mapreduce2GCSappengine-mapreduceのBlobLineInputReaderを使用したもので、WordCount対決を行ってみた。

・WordCount処理対象
10MB(MegaByte)のテキストファイルをshard数16でWordCount

●結果
【WordCount処理時間】
appengine-mapreduce00:09:53.225
appengine-mapreduce2GCS00: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.)
(平均処理数:1762Map処理/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.)
(平均処理数:2012Map処理/Task

なんと!GCS連携しているMapReduce処理のほうが早いという結果になった。
(Outputが正しいか検証したが、両者とも問題なかった。)
上記から見て取れるようにio-write-bytesに関してGCSの方が、
高速であることが分かる。
(ただし、GCSのほうはバケットに溜まったファイル群をリフレッシュしていた。
これが要因だとすると、不要なファイルは出来るだけ消しておくほうが良い?)

【まとめ】

今回は10MBというビッグデータとは決して言えないファイルを対象とした
検証であったので、妥当とは言えないかもしれない。
ただ、GAEで手軽に並列処理を行えるというのはとても画期的で、
有用であると考えられる。(中規模のデータであれば十分)
今後はさらに発展させたMapReduceのアプリケーションをGAEで
作っていけたらと考えてる。
また、この計測結果も更新していこうかな。