2013年2月2日土曜日

"m3.2xlarge"上で"s3cmd (& gnu paralell)"でS3にアップロードしてみる

スズキです。

下記でS3へのアップロード時間の短縮を、並列にプログラムを実行して試しましたが、
"s3cmd (& gnu paralell)"で多重度を変えてS3にアップロードしてみる
EC2のスペックが"t1.micro"の場合は、10MByteのファイルを30個アップロードするのに、
多重度を調整しても1/3程度(30秒から10秒)までしか短縮できませんでした。

1ファイル、平均1秒程度でアップロードしており、シリアルにアップロードすれば、
そのまま、30倍の30秒かかるのは計算通りですが、並列度を30にすれば、
30ファイル同時に1秒でアップロードするので、全体でも1、2秒でアップロードできると
思いきや、そうは問屋が卸してくれませんでした。

しかし、もしかしたら、EC2のタイプ(t1.micro)のリソースのキャパシティ(制限?)的な
可能性も高いので、今回は、よりスペックの高いタイプ、せっかくなので東京リージョンで
利用できるようになったばかりの下記M3シリーズ(m3.2xlarge)で試してみました。
【AWS発表】EC2のM3インスタンスが全リージョンで利用可能に。
さらにEC2の料金とリージョン間の転送料金を値下げ。

"m3.2xlarge"への変更




"m3.large"のスペック(8 virtual cores x 3.25 ECU / 30 GiB memory)

# top
top - 14:50:40 up 6 min,  1 user,  load average: 0.06, 0.05, 0.00
Tasks: 157 total,   1 running, 156 sleeping,   0 stopped,   0 zombie
Cpu0 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu2 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu3 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu4 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu5 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu6 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu7 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 30822996k total,  717008k used, 30105988k free,    9460k buffers
Swap: 1048568k total,       0k used,  1048568k free,  346052k cached

S3へのアップロード


まずは、基準となる"t1.micro"での結果です。
今回は下記の"-j 0"というオプションをつけて実行しています。
-j (-P) N

Number of jobslots. Run up to N jobs in parallel.
Nは並列に実行できるジョブの数です。
0 means as many as possible.
0にすると可能な限り実行します。
Default is 100% which will run one job per CPU core.
デフォルトは一つのCPUコアにつき一つです。
それでも冒頭で紹介した記事の内容と同じ10秒程度でした。
# time find -name "test-*" | parallel -j 0 s3cmd --no-progress put {} s3://www.suz-lab.com/tmp/
File './test-000028' stored as 's3://www.suz-lab.com/tmp/test-000028' (10485760 bytes in 3.2 seconds, 3.09 MB/s) [1 of 1]
...
File './test-000002' stored as 's3://www.suz-lab.com/tmp/test-000002' (10485760 bytes in 1.6 seconds, 6.39 MB/s) [1 of 1]

real 0m9.461s
user 0m5.850s
sys 0m3.145s

次に、"m3.2xlarge"で同様のコマンドアップロードしてみますが、
なんと、2秒程度まで劇的に短縮できてしまいました!
# time find -name "test-*" | parallel -j 0 s3cmd --no-progress put {} s3://www.suz-lab.com/tmp/
File './tmp/test-000010' stored as 's3://www.suz-lab.com/tmp/test-000010' (10485760 bytes in 0.7 seconds, 14.65 MB/s) [1 of 1]
...
File './tmp/test-000005' stored as 's3://www.suz-lab.com/tmp/test-000005' (10485760 bytes in 1.2 seconds, 8.46 MB/s) [1 of 1]

real 0m2.115s
user 0m4.962s
sys 0m2.695s

せっかくなので、更に最適化してみます。今回は30ファイルのアップロードを
8コアで行うので、1コアあたり4ジョブを並行に実行すれば、一気にすべて
アップロードできることになります。

なのでオプションを"-j 400%"(コアあたり4ジョブの並列実行を割り当てる?)にして
アップロードしてみました。
# time find -name "test-*" | parallel -j 400% s3cmd --no-progress put {} s3://www.suz-lab.com/tmp/
File './tmp/test-000013' stored as 's3://www.suz-lab.com/tmp/test-000013' (10485760 bytes in 0.5 seconds, 18.21 MB/s) [1 of 1]
...
File './tmp/test-000011' stored as 's3://www.suz-lab.com/tmp/test-000011' (10485760 bytes in 0.7 seconds, 15.19 MB/s) [1 of 1]

real 0m1.669s
user 0m4.955s
sys 0m2.705s
とりあえず、1.5秒程度とさらに速くなってはいますが、ここまで来ると分散の範囲内で、
速くなってるわけではないかもしれません...

というわけで、EC2のタイプを大きなものにすることにより、S3へのアップロードの
実質的な多重度を上げることができ、より短時間でファイルがアップロードできることが
わかりました。

また、"gnu parallel"は多重度をコアあたり(-j 400%)で指定できるので、
スケールアップなどで、(CPU)スペックが頻繁に変わってしまうようなシステムに対して、
コアが増えても多重度の変更不要なスクリプトを用意することができそうです。
まさに、クラウド向きの仕様ではないかと思います。

はやく、"m3.2xlarge"を"t1.micro"に下げないと、クラウド・マルサに怒られる...
--------
http://www.suz-lab.com

0 コメント: