Redisのレイテンシースパイクと99パーセンタイル
原文は Salvatore Sanfilippo により に公開されました。 このブログを購読する
StripeのRedisに関するブログ投稿で興味深い点の一つは、テスト中に取得したレイテンシーのグラフを掲載していることだ。Redisがデータをディスクに永続化するためには、fork()システムコールを呼び出す必要がある。通常、物理サーバーや大半のハイパーバイザーでは、プロセスが大きくてもforkは高速だ。しかしXenではforkが遅く、特定のEC2インスタンスタイプ(そして他の仮想サーバープロバイダーでも)では、親プロセスがディスクへの永続化のためにforkするたびに深刻なレイテンシースパイクが発生する可能性がある。Stripeのグラフはこの点について非常に明確だ。

想像できる通り、fork中にレイテンシーテストを実行すると、親プロセスがforkする瞬間をまたいだすべてのリクエストは最大で1秒程度遅延する(上のグラフを例に取った場合であり、プロセスサイズやEC2インスタンスが何だったのかは定かではない)。これにより高レイテンシーのサンプルが多数生じ、99パーセンタイルの結果に影響を与えることになる。
この挙動を改善するためにインスタンスタイプや設定、セットアップなどを変更するのは良い考えだし、たった1つのリクエストのレイテンシーが高すぎることさえ許容できないユースケースも存在する。しかし、30分ごとに1秒のレイテンシースパイクが発生すること(AOFを適切なリライトトリガーで使っている場合はそれ以上の間隔になる)が、リクエスト全体に均等に分散したレイテンシースパイクとは大きく異なるということは、どうやら自明ではないようだ。
スパイクが均等に分散している場合、ページ生成のためにRedisサーバーに対して複数のリクエストを実行する必要があるとすれば、ページビューがレイテンシーのペナルティを被る可能性は非常に高くなる。これはサービス品質に大きな影響を与えかねない。詳しくはこちらのリンクを参照してほしい: http://latencytipoftheday.blogspot.it/2014/06/latencytipoftheday-most-page-loads.html。
しかし、30分ごとに1秒のレイテンシーというのは全く別物だ。まず、リクエスト数が増えるほど良好なレイテンシーを示すパーセンタイルは改善する。リクエストが多ければ多いほど、この1秒間のレイテンシーがサンプル中で過大に代表される可能性は低くなるからだ(仮に1分あたり1リクエストしかなく、そのうちの1つが高レイテンシーに当たった場合、毎秒100リクエストある場合と比べて、99.99パーセンタイルへの影響ははるかに大きくなる)。
第二に、ほとんどのページビューは影響を受けない。1秒の遅延を経験するのは、fork呼び出しをまたいでリクエストを行ったユーザーのみだ。それ以外のリクエストが平均レイテンシーより著しく悪いレイテンシーに遭遇する確率は極めて低い。また、100件のリクエストからなるページビューであっても、forkのタイミングをまたいだ場合の遅延は1秒を超えることはないという点にも注意してほしい。fork()呼び出しが終了すれば、リクエストはすぐに完了するからだ。
結論として、個々のリクエストに対して厳格なレイテンシー要件があるのであれば、時折リクエストが1秒遅延しうるセットアップが大きな問題であることは明らかだ。しかし、良質なサービスを提供することが目的である場合、レイテンシースパイクの分布が結果に大きな影響を与える。Xen上でのforkに起因するRedisのレイテンシースパイクは、時間軸上の孤立した点であり、ページビューが多数のRedisリクエストから構成されている場合でも、影響を受けるページビューの割合はレイテンシースパイクの総時間の割合に比例する。このケースでは1800秒ごとに1秒なので、影響を受けるページビューはわずか0.05%に過ぎない。
レイテンシーの特性を単一の指標で捉えるのは難しい。完全なパーセンタイル曲線やスパイクの分布を見ることで、より正確な全体像が得られる。一般的に、経験則は調査を始める上で有用な出発点であり、平均レイテンシーが貧弱な指標であることも概ね真実だ。しかし、経験則を絶対的な真理へと昇格させることにも弊害はある。多くの複雑な事柄は依然として複雑なままであり、我々が過度に単純化したいと願うかどうかに関わらず、綿密な検証を必要とするからだ。
同時に、EC2インスタンスにおけるforkの遅延は、今日最も人気のある実行環境の一つにおいてRedisユーザーにとって最悪の体験の一つでもある。そこで私は現在、EC2でのRedisの定期的なテストを開始している。まもなくRedis公式ドキュメントにEC2固有の最適化に関するページを用意し、永続化を無効にしたmaster-slavesレプリカをより安全に運用する方法も提供する予定だ。
今すぐEC2 + 永続化を無効にしたRedis masterが必要な場合、最も簡単に導入できる「quick fix」は、Redisインスタンスの自動再起動を無効にし、フェイルオーバーにSentinelを使用することだ。これにより、クラッシュしたmasterが自動的に復帰して利用可能になることがなくなり、Sentinelによってフェイルオーバーされる。システム管理者は、フェイルオーバーが成功し新しいactiveなmasterが存在することを確認した後、手動でmasterを再起動すればよい。
追記: EC2、Xen、fork時間に関する興味深い情報が含まれたHacker Newsのスレッドをぜひチェックしてほしい: https://news.ycombinator.com/item?id=8532851。また、すべてのEC2インスタンスが同じというわけではなく、特定のタイプではベアメタルシステムに匹敵する優れたfork時間を提供している: https://redislabs.com/blog/testing-fork-time-on-awsxen-infrastructure#.VFJQ-JPF8yF
記事をランダムに読む
コメント
ログインしてコメントする