Slack 社の Secured API Acceleration with Engineers from Amazon CloudFront and Slack という資料を読んでいたら、「CloudFront をはさんだらキャッシュしないAPIアクセスでも速くなった :D」 と書いてあったが、CloudFront (例えばjp)から ELB (例えばus) までは依然として latency があるわけで、本当に速くなるのか懐疑的だったので自分でも試してみた。

このスライドの11ページに速くなった理由は5つ書いてあり、以下のとおり。

  • (1) CloudFront Latency Based Routing
  • (2) TCP/IP Optimizations for the Network Path
  • (3) Keep-Alive Connections to reduce RTT
  • (4) AWS Backbone Network
  • (5) SSL/TLS Optimizations

(1) CloudFront Latency Based Routing については、日本のエッジロケーションを自動選択してくれるんだから、まぁそうだよね、という感じで、 (5) SSL/TLS Optimizations についても、距離が近くなればSSL確立まで速くなるのは、まぁわかる、という感じ。

(4) AWS Backbone Network については、なにかあるんだろうが、実際速くなるんだろうか、という気持ちで、 (2) TCP/IP Optimizations for the Network Path と (3) Keep-Alive Connections to reduce RTT については、何を指しているのかがスライドには書いてなくて、わからん、という感じ。試してみたほうが早いな、と。

やったこと

  • us-east-1 に t2.nano で Amazon Linux なインスタンスを立て、nginx-1.8.1-3.27.amzn1.x86_64 を yum install して空の index.html を返すようにしておく(素の設定のまま)
  • us-east-1 に ELB を立てて作ったインスタンスを追加しておく (ELB を作るのは、CloudFront が ELB か S3 しかオリジンに設定できないため)
  • CloudFront を立てて、ELB をオリジンに設定。キャッシュを一切しないように設定しておく

この状況で日本のオフィスから以下の ruby スクリプトを実行して、ELBを指定した場合とCloudFrontを指定した場合の時間を計測した。

エッジロケーションまでの距離が近くなればSSL確立の時間が短くなっているのはわかっているので、あえてhttpsではなくhttpで計測して、(4) AWS Backbone Network にどれぐらいの効果があるのかを検証した。

require 'net/http'
fqdn = 'xxxxxx'

started = Time.now.to_f
# no keeepalive
10.times do
  Net::HTTP.get fqdn, '/index.html'
end
puts "#{Time.now.to_f - started} sec"

結果

  • ELB: 4.051 sec
  • CloudFront: 2.672 sec

確かに速くなった。

補足: なお ap-northeast-1 の ec2 に対して直接アクセスする同様の試験を行うと 0.3000 sec 程度^^;

まとめ

確かにキャッシュなしでも (4) AWS Backbone Network の効果で、1.53 倍程度速くなるようだ。さらにSSL確立も速くなるので実用としてはもう少し速くなるだろう。 ちょうど us リージョンに立てているけれど、日本からもアクセスされる API サーバがあるので、使ってみようかな、という気持ち。

ところで、

  • (2) TCP/IP Optimizations for the Network Path
  • (3) Keep-Alive Connections to reduce RTT

については依然として何を言っているのかわからないけど、CloudFront <=> ELB 間は keepalive 接続してたりするのだろうか。スライド書いた人に聞いたほうが早いかな。