S3のダウンロード速度を1.5〜4.5倍高速化する怪しげな方法

バケットのIPアドレスを適切なものに固定することで、期待値でいうと1.5倍、最大で4.5倍程度高速にダウンロードできます。
この方法は非常に効果が高いですが、非公式なものであり、ある日突然破綻する可能性もありますので自己責任でお願いします。

S3のバケットとエンドポイント

まずは前提知識として、S3の名前解決について説明します。
S3のバケット "mybucket" というバケットを東京リージョンに持っているとします。するとそのバケットのドメイン名は

mybucket.s3.amazonaws.com

になります。これをエンドポイントと呼びます。このバケットの中にあるファイル "hello.txt" にアクセスする場合には、

http(s)://mybucket.s3.amazonaws.com/hello.txt

というようなURLを用います。*1

エンドポイントのIPアドレス

この mybucket.s3.amazonaws.com は東京リージョンの場合、 s3-ap-northeast-1-w.amazonaws.com のCNAMEです。*2
s3-ap-northeast-1-w.amazonaws.com について調べてみると、

$ dig s3-ap-northeast-1-w.amazonaws.com
  :
s3-ap-northeast-1-w.amazonaws.com. 60 IN A     27.0.1.77
  :

となり、 27.0.1.77 を指しているAレコードであることが分かります。
ある日、実はこのIPアドレスは 27.0.1.77 を含めて3パターンあることに気づきました。調べてみましょう。

for i in {1..100}; do dig @ns-911.amazonaws.com s3-ap-northeast-1-w.amazonaws.com A ; done | grep ^s3 | cut -f3 | sort | uniq -c | sort -n
     33 27.0.1.207
     33 27.0.2.77
     34 27.0.1.77
  • 27.0.1.207
  • 27.0.2.77
  • 27.0.1.77

という3パターンがランダムに返されるようです。
実はこの3つのIPアドレスは、どれを使うかによってダウンロード速度が4.5倍ほど異なります。

ベンチマーク

東京リージョンのS3バケットに 100KB のファイルを置いて、EC2インスタンス(c1.xlarge)でのダウンロード速度を計測しました。
EC2インスタンスは、2つのAvailabilityZone(ap-northeast-1a、ap-northeast-1b)にそれぞれ1台ずつ立てて比較しました。
c1.xlargeという大きなインスタンスを選んだのは、Xenのホストである物理マシンの専有率を高くするためです。*3

ベンチマークにはabを使って以下のように行いました。

$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.1.77/100k.dat
$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.2.77/100k.dat
$ ab -n10000 -c 10 -H "Host: mybucket.s3.amazonaws.com" http://27.0.1.207/100k.dat

平均のrequest/secをグラフにしたものが以下です。数値が大きいほど高速です。
f:id:mirakui:20111210180643p:image
ap-northeast-1aのインスタンスでは27.0.1.77から、ap-northeast-1bの場合は27.0.1.207からダウンロードするのが高速であることが分かります。逆に、 27.0.2.77 を引いてしまった場合は大変に残念なことになります。

randomとなっているのは、IPアドレスを固定せず、AWSのネームサーバがランダムに返してくるIPアドレスをそのまま使った場合の速度です。つまりこれが普段の速度だとみなしていいでしょう。

結論

同じ東京リージョン内でS3->EC2という転送をする場合、/etc/hostsに

# ap-northeast-1aの場合
27.0.1.77 mybucket.s3.amazonaws.com
# ap-northeast-1bの場合
27.0.1.207 mybucket.s3.amazonaws.com

みたいに書けば普段の1.5倍ほどのダウンロード速度を得ることができます。
EC2ではない場合でも、27.0.2.77以外を使うようにすればそれなりの高速化が見込めるでしょう。今だけかもしれないけどね!!

なんでこんなことに気づいたのか

S3を使ったとあるサーバを運用しているのですが、ある日名前解決がボトルネックになっている思って/etc/hostsに上記のような記述をしてみたところ、指定するIPアドレスによってえらく速度が変わっていることに気づきました。

3ヶ月前くらいからこの現象を観察していたのですが、これらの転送速度は日によって変わったりはせず、速いIPアドレスは3ヶ月間安定して速く、遅いものは安定して遅いという状態が続いています。
ただし今後はどうなるか分かりません!!

まとめ

バケットのIPアドレスなんてAmazonの内部的なアレなので、ある日突然増えたり減ったり変わったりする可能性が高いですが、このリスクは監視を入れるなどしてある程度技術的に補えると思うので、S3の転送速度に困っている方は試してみるといいかもしれません。

あと今回は東京リージョンでのみ試したので、他のリージョンの事情はまったく知りません。なにか情報があれば教えて下さい。

DO IT AT YOUR OWN RISK!!!!

*1:この場合はhello.txtをpublicにする必要があります

*2:ap-northeast-1は東京リージョンを指す

*3:EC2では物理マシンの占有率が高いほどネットワークが安定する