インフラ部 SRE グループの渡辺(@takanabe)です。普段はクックパッドのグローバルサービス (https://cookpad.com/us) のインフラの開発や運用をしています。
クックパッドは、21 言語・67 カ国以上を対象にサービスを展開しています ( 2017 年 6 月末時点)。今後もその数を増やしていく予定です。 世界中で使われるサービスのインフラを開発していく上で、乗り越える必要がある課題は沢山ありますが、その中でも、ユーザが利用するクライアントとクックパッドのインフラをむすぶネットワークのレイテンシは特に大きい課題です。 本稿ではなぜグローバルに利用されるサービスにおいて、ネットワークレイテンシが問題になるのか、また、クックパッドではネットワークレイテンシをどう計測し改善しようとしているかについて解説します。
ネットワークレイテンシとは
ユーザがサービスにリクエストを送ってからレスポンスを受け取るまでにかかる時間 (レスポンスタイム) は、主にネットワークレイテンシとアプリケーションの処理時間の合計です。 アプリケーションの処理時間短縮もサービスのレスポンスタイム改善には有用ですが、グローバルに展開されたサービスにおいてはネットワークレイテンシも大きなオーバーヘッドになりえます。この両方を改善していくことがユーザ体験向上のために重要です。本稿ではネットワークレイテンシについてご紹介します。
ネットワークレイテンシは大きく分けると以下の 4 つから構成されています。
- 伝播遅延: クライアントがパケットを送出してから私達の管理するサーバに到達するまでの時間(あるいはその逆方向の通信にかかる時間)
- 伝送遅延: パケットがリンクに載るまでの時間
- 処理遅延: ルータがパケットのヘッダをチェックして宛先を決定するまでの時間
- キューイング遅延: ルータのパケット処理待ち状態の際にバッファキューで待機する時間
一方で私たちが普段ネットワークレイテンシという言葉を使う場合は、往復の伝搬遅延、つまり Round-trip-time を意味することが多いです。本稿でもネットワークレイテンシ(以下レイテンシ)を Round-trip-time (以下 RTT ) の意味で使います。
グローバルサービスとレイテンシ
クックパッドのグローバルサービスのサーバは現在 AWS の米国東部リージョンに集約されているため、サービスの通信は基本的にはユーザの居住地と米国との間を往復することになります。
サーバが米国東部リージョンに集約されていることで、米国や米国近辺に住んでいるユーザはレイテンシが小さくなります。一方で、アジアや中東など地理的に遠い国に住むユーザにとってはレイテンシを悪化させる要因の一つとなっています。例えばリクエストがネットワークを伝わる速度を光速( 300,000 km / sec)とし、日本から米国東部までの距離を 11,000 km としたとき、レイテンシは約 73.3 ms になります。現実には、サーバまでのネットワークの経路は一直線ではありません。加えて、伝送において 300,000 km / sec もの速度が出ることはないためレイテンシはさらに大きくなります。*1
例として、東京の私の家から Amazon S3 の東京リージョンのエンドポイントと米国東部リージョン( us-east-1 )のエンドポイントに ping を打つと以下のように平均レイテンシは前者は約 22.2 ms、後者は約 186.2 ms でした。
# AWS の東京リージョンのエンドポイントに ping を打った場合 > ping -t 5 s3-ap-northeast-1.amazonaws.com PING s3-ap-northeast-1.amazonaws.com (52.219.68.108): 56 data bytes 64 bytes from 52.219.68.108: icmp_seq=0 ttl=50 time=21.811 ms 64 bytes from 52.219.68.108: icmp_seq=1 ttl=50 time=20.666 ms 64 bytes from 52.219.68.108: icmp_seq=2 ttl=50 time=24.138 ms 64 bytes from 52.219.68.108: icmp_seq=3 ttl=50 time=22.797 ms 64 bytes from 52.219.68.108: icmp_seq=4 ttl=50 time=21.750 ms --- s3-ap-northeast-1.amazonaws.com ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 20.666/22.232/24.138/1.167 ms # AWS の米国東部リージョンのエンドポイントに ping を打った場合 > ping -t 5 s3.us-east-1.amazonaws.com PING s3.us-east-1.amazonaws.com (54.231.120.114): 56 data bytes 64 bytes from 54.231.120.114: icmp_seq=0 ttl=43 time=179.987 ms 64 bytes from 54.231.120.114: icmp_seq=1 ttl=43 time=208.230 ms 64 bytes from 54.231.120.114: icmp_seq=2 ttl=43 time=176.016 ms 64 bytes from 54.231.120.114: icmp_seq=3 ttl=43 time=182.457 ms 64 bytes from 54.231.120.114: icmp_seq=4 ttl=43 time=184.399 ms --- s3.us-east-1.amazonaws.com ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 176.016/186.218/208.230/11.357 ms
164 ms のレイテンシの差がユーザに与える影響
HTTP がクライアントとサーバ間の通信の往復から成っていることを考えると、この 164 ms のレイテンシの差がユーザが快適にサービスを使えるかに大きな影響を与えます。例えば、クックパッドは HTTPS を利用して暗号化された安全な通信をユーザに提供しています。 HTTPS に利用されている TLS 接続を確立するには下図のように TCP ハンドシェイクに 1.5 往復、 TLS ハンドシェイクに 2 往復の通信が必要です。
(https://hpbn.co/transport-layer-security-tls/#tls-handshake Figure 4-2. TLS handshake protocol より引用)
TLS ハンドシェイクの Client Hello メッセージは TCP ハンドシェイクの ACK と同じタイミングで送出されることから、 TLS 接続には正味 3 往復必要になります。 つまり RTT の 3 倍の時間がかかります。
この TLS 接続が成立するまでの時間を先程例に上げた東京と東京リージョンの往復で換算すると、22.2 x 3 = 66.6 msの時間がかかることになります。一方で、東京と米国東部リージョンの往復で換算すると、186.2 x 3 = 558.6 msの時間がかかることになります。
その差は 492 ms です。 この数値は一見問題にならないようにも感じられますが、Jakob Nielsen の著書 Usability Engineering ではレスポンスタイムには3つの境界値が存在すると言われています。
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
1.0 second is about the limit for the user’s flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
10 seconds is about the limit for keeping the user’s attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
(Jakob Nielsen, “Usability Engineering”, 1993, pp 135)
これによると人間はリクエストを送出して 100 ms 〜 1 sec 以内のレスポンスでも遅延を感じるとされています。つまり、 164 ms のレイテンシの違いが生む 492 ms の差はユーザの体験を悪化させる要因に成り得るのです。
今までのクックパッドのレイテンシ対策
クックパッドのグローバルサービスは、日本のサービスとは使われているリージョンやコードベースが異なりますが、cookpad.com ドメインを共有しています。 同じドメインにおいて異なるアプリケーションにリクエストを振り分けるため、ロードバランサ (ELB) 下のリバースプロキシでリクエストがグローバルサービスのもの (/uk, /id など) か日本のサービスのものかを判定してルーティングをしています。 ただ、アプリケーションがリージョンを跨いでいるのにリバースプロキシを 1 リージョンに置くだけではリバースプロキシが無いリージョンへのリクエストが遅くなってしまうため、 同様の設定がされたリバースプロキシを東京 (ap-northeast-1) と米国東部 (us-east-1) リージョンに配置し、Amazon Route 53 のレイテンシベースルーティング*2を利用して DNS ベースでユーザーからレイテンシの低いリージョンへ最初にリクエストを送信させるようにしています。 これにより、ユーザーから近いリージョンのロードバランサにアクセスできるというメリットがあります。
以上のようにレイテンシを増加させる要因はサーバと利用するユーザの所在や使っている技術により異なります。クックパッドの場合サービス利用者が多いインドネシアなどではこのレイテンシの問題は顕著に現れてきています。
レイテンシの計測方法
レイテンシを改善するにはレイテンシがどのような要素から成っており、何をした時にどのくらい改善されたのか、あるいは悪化したのかを定量的に評価しなければなりません。これを実現するにはレイテンシやレスポンスタイムなどのメトリクスを計測し続ける必要があります。
サービスのレイテンシを計測する方法を大別すると、以下の二つが挙げられます
- Synthetic Monitoring
- Real User Monitoring(RUM)
Synthetic Monitoring は専用の監視サーバからリクエストを送出して計測します。一方で RUM はユーザのクライアント上で実際にかかった時間そのものを収集します。この2つの方法はどちらが良いと言うわけではなく、集計の粒度も計測する対象も異なるため組み合わせて使うものです。今回は平均的な統計情報をまず取得し、その上でレイテンシを悪化させている要因を分析するという目的があり、Synthetic Monitoring を導入することにしました。
Synthetic Monitoring “Catchpoint”
クックパッドは Catchpoint Systems の Synthetic Monitoring サービス(以下 Catchpoint )を利用しています。 Catchpoint を選択した理由は他の Synthetic Monitoring ツールと同様の日別パフォーマンスの比較ができる点、 Waterfall Chart などの基本的な機能を有している点、 UI がシンプルである点で条件を満たしており、加えて監視サーバのノード数とロケーションの数が他社のものより多いためです*3。サービスの世界展開を目指しているクックパッドにとってこれは重要な機能のひとつです。
Catchpointによるパフォーマンスの分析
パフォーマンス解析機能による全体像の把握
Catchpoint では計測対象のエンドポイント、監視サーバ群、監視の頻度など監視に関する条件を定義するテストを作る必要があります。この記事では https://cookpad.com/us に対して複数の国の監視サーバからアクセスする “Global top page” というテストを用意しました。
パフォーマンス解析の機能を使うことでこの Global top page テストで定義した各国の監視ノードから https://cookpad.com/us にアクセスした際のレスポンスタイム(ms)を確認できます。例えば、2017年2月25 - 27日の3日間を対象に横軸を日時、縦軸をレスポンスタイムにして描画するとこのようなグラフが得られます。
ご覧の通りテストで選択した監視サーバの国別のレスポンスタイムを俯瞰することができています。これをみるとインドネシア、アルゼンチン、エジプトなどの国のレスポンスタイムが相対的に悪いですね。グラフの上にポインタを乗せると他のメトリクスを確認できたり、この時間帯の Waterfall chart に飛ぶこともできます。 Waterfall chart については後述します。
また、 Geo chart という機能を使うと監視サーバそれぞれでパフォーマンスメトリクスの一つを地図上で可視化できます。以下ではサーバにリクエストを行って最初の1バイトが到着するまでの時間を示す Time To First Byte(TTFB)を表示しています。インドネシアは TTFB が他国と比較して長いことがわかります。物理的な距離が影響しているかもしれません。
このようにおおまかなパフォーマンスメトリクスをパフォーマンス解析機能で確認し、当たりをつけ、その後より細かい分析を行うのが自然な流れかと思います。次は上記で確認したインドネシアのパフォーマンスを Waterfall chart で分析していきたいと思います。
Waterfall chartを使ったパフォーマンスボトルネックの分析
Waterfall chart の画面では特定のエンドポイントに特定の監視サーバからアクセスしたときのパフォーマンスメトリクスの詳細な分析ができます。例えば、2017年2月26日12時にインドネシアのジャカルタの監視サーバから https://cookpad.com/us ( Global top page テストを利用)にアクセスした時の Waterfall chart の画面はこのような感じです。ご覧の通り、名前解決や TLS 接続などを含む TTFB 、レンダリング開始、対象のページのレンダリングが完了したことを表す Document Complete などの時間が確認できます。
また Waterfall chart を見るとどのリクエストがパフォーマンスに悪影響を与えているかが簡単にわかります。 Global top page テストの場合 cookpad.com/us にアクセスした際の最初のリクエストの TTFB で全体の約1/3の時間を要しています。さらに、TTFB の内訳を確認すると名前解決や TLS 接続に多くの時間を割いている事がわかります。本稿の最初に TLS ハンドシェイクについて言及しましたが、ここで計測された TLS 接続に必要な時間を短くする事は、すなわちレイテンシの改善につながります。
またいわゆるクリティカルレンダリングパスが赤く塗りつぶされているのでどのリクエストをパフォーマンス改善のターゲットにすれば良いのかが分かりやすくなっています。以上が Cacthpoint の基本的な機能と使い方の紹介になります。他にもダッシュボードを作って public url で共有できたり、トランザクション処理のあるリクエストのボトルネックを解析したりと様々なことができます。
クックパッドでの Catchpoint の使用例
ここまでわかればこれらをどのように改善すべきかという手段の話ができるようになりますね。当初の目的の通りレイテンシを改善するのであれば相関関係が強い名前解決、TLS 接続、TTFB などを改善する方法を少し検討してみます。
サーバのマルチリージョン展開によるレイテンシ改善効果の調査
米国東部に集約しているサーバをインドネシア付近のデータセンタにも展開した場合 RTT はどのように変わるでしょうか。簡単な効果測定は Catchpoint の Instant Test 機能(定期的な計測ではなく任意の監視サーバから任意のエンドポイントに単発のリクエストを実行する機能)を使うことでできます。インドネシアの監視サーバから AWS の米国東部( us-east-1 )、東京( ap-northeast-1 )、シンガポール( ap-southeast-1 )の各リージョンに対して ping を打った結果を比較すると、インドネシアは米国東部や東京よりシンガポールの方が RTT は小さくなることがわかります。
AWS のシンガポールリージョンを使うことでインドネシアのレイテンシは改善されそうですね。わざわざ現地に行かずとも世界中の監視サーバからのリクエストのパフォーマンスが計測できる Instant Test はとても便利です。
CDNの導入によるレスポンスタイム改善効果の調査
CDN の導入もレイテンシの改善に効果があります。CDN は主にキャッシュ用途で使われることが多いですが、今回は TCP と TLS の 終端のためだけに使っています。ユーザーとの接続を近いサーバで終端することで、レイテンシに大きく寄与する TCP および TLS ハンドシェイクの時間を短縮します。CDN のエッジサーバからオリジンとなるアプリケーションサーバへの TLS 接続は HTTP Keep-Alive により再利用することで、さらにレイテンシを短縮することができます。
クックパッドのグローバルサービスでも全てのリクエストを CDN を経由させる施策を進めています。しかし、全てのユーザに大きな影響がある上、それなりにコストをかける必要があるため、 CDN 導入後に改善効果がありペイするのか、 どの CDN を導入すれば良いかなどの検証を Catchpoint で行いました。 以下は CDN 利用前と Fastly と X 社の CDN を利用した場合のある API のレスポンスタイムの比較です。
これを見るとインドネシアのユーザに対しては Fastly と X 社 共にレスポンスタイムの改善効果があるとわかります。現在はグローバルサービスには部分的に Fastly を導入しています。TLS 接続や全体のレスポンスタイムは以下のようになりました。期待していた通り、 TLS ハンドシェイクの短縮やレスポンスタイムの改善がされています。
余談ですが、2017年7月中頃までは Fastly を導入するとアルゼンチンのユーザのレスポンスタイムは悪化するという計測結果が出ていました。その時点で Fastly もブラジルにデータセンタ、 いわゆる Point of Presence(POP) を持っていたのですが期待した結果が得られなかったため原因を調べました。 すると、当時アルゼンチンからのトラフィックではブラジルの POP が使えない状態であることがわかりました。その代わりに米国西部の POP が使われていたのです。計測せずに導入していた場合、大きなコストをかけてユーザ体験を悪化させていた可能性がありました。現在は Fastly でもブラジルの POP のキャパシティが拡張*4されて POP 数も増えました*5。南米のユーザのレスポンスタイムを改善する際の一つの手段となり得ると思います。
おわりに
この記事ではクックパッドのグローバルサービスにおいてなぜレイテンシが問題になっているのか、それを Catchpoint でどのように計測改善しようとしているのかについて書きました。
Catchpoint で日々レイテンシの計測をしているため問題の解決に集中できる環境が整いましたが、グローバルサービスのパフォーマンス改善はまだ始まったばかりです。今後は RUM の導入やパフォーマンス計測によって得た結果をレイテンシやレスポンスタイムの改善に活かし、世界中のユーザがサービスをより快適に使えるようにしていきたいと思っています。
参考文献
- Jakob Nielsen, “Usability Engineering”, 1993
- A・S・タネンバウム, “コンピュータネットワーク第4版”, 2003
- 竹下隆史, 村山公保, 荒井透, 苅田幸雄, “マスタリングTCP/IP 入門編 第5版”, 2012
- Ilya Grigorik, “High Performance Browser Networking”, https://hpbn.co/