1/01/2017

あなたは間違ってロードバランシングしていませんか?

ACM Queueに掲載された論文。ロードバランサーの設計、運用に関する注意点。

Everything Sysadmin: あなたは間違ってロードバランシングしていませんか?


誰でもロードバランサを使用できるが、適切に使うことはとても難しい


トーマス・A・リモンセリ (Thomas A. Limoncelli)


最近読者が、容量を追加したり、障害へのサービスの回復機能を持たせるため、ロードバランサを使うのが良いことかどうかを尋ねに私に連絡してきた。その答えは: どちらもロードバランサの適切な使用法である。しかし、問題はロードバランサを使用するほとんどの人が間違って使っていることである。

今日では、ロードバランサを使用するウェブ中心、サービス中心の環境が広がっている。しかし、私はほとんどの場合、それらは間違って使われていると断言する。問題を理解するため、最初に一般的なロードバランサについて少し議論する必要がある。そうすることで、我々は問題と解決策を検討できる。

ロードバランサは要求を受け取り、複数のマシンに要求を配信する。これらのマシンは同じサービスを提供するのでレプリカと呼ばれる。単純に考えるため、これらはウェブブラウザからのHTTP要求であると仮定するが、ロードバランサはHTTPS要求、DNSクエリ、SMTP(メール)接続、多くの他のプロトコルでも使われる。ほとんどの最新のアプリケーションはロードバランサの背後で動作するよう設計されている。

容量対レジリエンスのためのロードバランシング

ロードバランサを使うには、容量を増やすこととレジリエンシーを改善することの2つの主な使用法がある。

容量を増やすためにロードバランサを使うのはとても単純である。一つのレプリカが、入ってくる負荷全体を処理するのに十分に強力でなくても、ロードバランサは複数のレプリカの間で負荷を分散できる。

一つのレプリカが100 QPS (1秒あたりのクエリ数)を処理できると仮定する。100 QPSより少なければ正常に動作する。もし、100 QPS以上やって来たら、レプリカは過負荷になり、要求を拒絶あるいはクラッシュする。どちらも幸せな状況とは言えない。

レプリカとして設定されたロードバランサの背後に2台のマシンがある場合、容量は200 QPSとなる。そして、3台のレプリカなら容量300 QPSを提供する。より多くの容量が必要なら、更にレプリカを加えることができる。これは水平方向の拡大である。

ロードバランサはレジリエンシーを改善するために使うこともできる。レジリエンシーは、障害を乗り切るための能力を意味する。個々のマシンが故障しても、システムはサービスを提供し続けなければならない。全てのマシンはいずれ故障する。それが物理特性である。レプリカが完璧に近い稼働時間だったとしても、ソフトウェアのアップグレードあるいは物理的にマシンの移設の必要性のような外部性のために、レジリエンシーのメカニズムは必要である。

ロードバランサは、一台のレプリカが故障しても、残りのレプリカが入って来る要求を処理できる十分な予備容量を残すことでレジリエンシーを実現できる。

例を続けると、4台のレプリカが400 QPSの容量を達成するためにデプロイされたと仮定する。現在、300 QPSを受信しているなら、各レプリカは約75 QPS (負荷の1/4)を受信する。一台のレプリカが故障したらどうなるか? ロードバランサは速やかに停止を検知してトラフィックをシフトし、各レプリカは約100 QPS受信する。各レプリカは最大容量で動作することを意味する。余裕はないが、許容範囲にある。

システムが400 QPSを受信したらどうなるのか? 通常の運用では、4台のレプリカはそれぞれ約100 QPSを受信する。もし、1台のレプリカが死ねば、残りのレプリカはそれぞれ約133 QPSを受信する。各レプリカは約100 QPS処理できるので、これは各レプリカは1/3ほど過負荷になることを意味する。システムはクロールが遅くなり、使用できないようになる。クラッシュするかもしれない。

ロードバランサがどのように使われるかの決定要因は、負荷が300 QPSを上回るか下回るかどうかである。300 QPS以下の場合、これはレジリエンシーのために使われるロードバランサとなる。301 QPS以上の場合、これは容量増のために使われるロードバランサとなる。

容量を増やすため、あるいはレジリエンシーを改善するためにロードバランサを使うことの差は、構成上の違いではなく運用上の違いである。どちらの場合もハードウェアやネットワーク(あるいは仮想ハードウェアと仮想ネットワーク)は同じ構成で、ロードバランサの設定も同じである。

N+1冗長性という用語は、1台のレプリカが停止した場合にシステムが正常に動作するために残りのN台のレプリカに十分な容量が残っているよう設定されたシステムを指す。予備容量がない場合は、システムはN+0である。2台のレプリカが停止するまで許容するシステムを可能にするN+2冗長性を設計することもできる。その他も可能である。

間違えて実行する3つの方法

ロードバランサが使われる2つの異なる方法を理解したので、ほとんどチームがどのように失敗しているかを検討してみよう。

レベル1: チームの意見が合わない

ロードバランサは容量を追加か、あるいはレジリエンシーを改善するのに使うのかチームのメンバーに尋ねて欲しい。チームでそれぞれの人が異なる意見を答えたとすると、間違った負荷バランスが行われている。

チームの意見が一致しないなら、チームのそれぞれのメンバーは異なるエンジニアリング上の決定を下すことになる。良くても、これは混乱につながる。最悪の場合、悩みの元につながる。

あなたはこのレベルにあるチームがいくつあるか驚くだろう。

レベル2: 容量が定義されていない

他の間違えそうなものはシステムの容量の測定方法の考えが一致しないことである。この定義無しに、このシステムがN+0あるいはN+1なのかが分からない。つまり、ロードバランシングが容量なのかレジリエンスのためなのか合意していなければならないが、あなたがどの方法を使っているのかどうかが分からない。

確実に知るためには、各レプリカの実際の容量を知る必要がある。理想的には各レプリカが処理できるQPSがどのくらいなのかを知りたい。N+1閾値(あるいは頂点)を計算する式は単純な計算である。悲しいことに、世界はあまり単純ではない。

単純にソースコードを調べて、各要求が必要とする時間やリソースを知り、レプリカの容量を特定することはできない。たとえ、レプリカの理論上の容量を知っていても、実験的に検証する必要がある。我々は科学者であり、無教養な人間ではない。

容量はベンチマークによって決められのが最善である。クエリが生成され、一定間隔の応答時間で持つよう様々な速度でシステムに送られる。200ミリ秒の応答時間があれば十分であると考えていると仮定する。50クエリ/秒を生成することによって始め、システムが過負荷になり、200ミリ秒よりも応答が遅くなるまで速度をゆっくり増加させる。応答時間が十分に速く返る最後のQPSレートがレプリカの容量と決定する。

数千あるいは数万のクエリを測定する際に、あなたはどのように応答時間を定量化するだろうか? 全てのクエリが同じ時間で実行されるわけでは無い。一つの長く続くリクエストは誤解を招く統計結果になるかも知れないため、平均を取ることはできない。平均もニ山分布がさらに分かりにくくする。(この詳細については、Thomas Limoncelli、Strata R. Chalup、Christina J. Hogan共著の「クラウドシステム管理の実践: 巨大分散システムの設計と運用 / The Practice of Cloud System Administration: Designing and Operating Large Distributed Systems, Volume 2」の第17章を参照してほしい)。

単純平均は不十分であるため、ほとんどのサイトはパーセンタイル値を使っている。例えば、要件は、応答時間の90パーセンタイルが200ミリ秒以上でなければならないとなる。これは最も極端な異常値を捨て去る最も簡単な方法である。多くのサイトは、David GoldbergとYinan Shanによる2015年の論文「統計的アノマリ検知のための特徴の重要性 / The Importance of Features for Statistical Anomaly Detection (https://www.usenix.org/system/files/conference/hotcloud15/hotcloud15-goldberg.pdf)」で説明されているMAD(中央絶対偏差)を使い始めている。

そのようなベンチマークを使う合成クエリを生成することがもう一つの課題である。全てのクエリが同じ時間掛かるわけでは無い。短いリクエストや長いリクエストがある。100 QPSを処理するレプリカは実際は80の長いクエリと120の短いクエリを処理しているかも知れない。ベンチマークは現実の世界を反映したミックスしたものを使わなければならない。

全てのクエリが読み取り専用、あるいはシステムを変更させないものなら、単純に1時間分の実際のクエリを保存して、ベンチマーク中に再生することができる。前の雇用主では、我々はサービスをベンチマークするために使われる110億の検索クエリのデータセットを持っていた。最初に、キャッシュをウォームアップするために10億クエリをシステムに送信する。パフォーマンスを測定するため、残っているクエリの間に測定結果を記録した。

全ての作業負荷が読み取りのみとは限らない。読み取りと書き込みのクエリの混在が必要なら、ベンチマークのデータセットやプロセスはさらいっそう複雑になる。読み取りと書き込みのクエリの混在が現実世界の状況を反映していることが重要である。

残念ながら、新しい機能の導入あるいはユーザアクセスパターンの予期しない変更の結果、クエリタイプの混在は徐々に変化するかも知れない。古い機能が新しい需要を獲得した時、今日200 QPSの容量を守ったシステムが明日には50 QPSに変わるかも知れない。

ソフトウェアのパフォーマンスはリリース毎に変化するかも知れない。各リリースで、想定容量が変化しないことを検証するためにベンチマークを行うべきである。

このベンチマークが手動で行われている場合、メジャーリリースでのみ実行されている可能性がある。ベンチマークが自動化されている場合、CI (継続的インテグレーション)システムに統合化することができる。本番環境で動作するリリースより著しく遅いリリースは失敗する。そのような自動化は手動タスクを取り除くため、単にエンジニアリング的な生産性を改善するだけではなく、リグレッションを引き起こす正確な変更を速やかに知るため、エンジニアリング的な生産性も強化する。たまにベンチマークが実行されるなら、パフォーマンスリグレッションを見つけるには、問題の原因となった変更を検査するために数時間あるいは数日要する。

理想的には、ベンチマークは稼働中のパフォーマンスを計測することによっても検証できる。2つの統計を比較すべきである。もし、できなければ、ベンチマークを正しく合わせなければならない。

ベンチマークがなぜそんなにも複雑なもう一つの理由はキャッシュである。キャッシュは予期しない副作用を伴う。例えば、直感的に見れば、システムはレプリカを増やすと早くなると期待する。多くレプリカが軽い仕事を行う。一方、キャッシュの利用率が低下するため、一部のアプリケーションはレプリカを増やすと遅くなる。レプリカがローカルキャッシュを持つなら、レプリカが非常に利用されるとキャッシュがヒットする可能性が高くなる。

レベル3: 監視しないが定義する

チームがやってしまう可能性があるもう一つの間違いは、これら全ての定義について同意しなければならないが、あなたは準拠しているかどうかを気付くための監視を行なっていない点である。

チームが、ロードバランサは容量とレジリエンス両方を改善するためと決定したと仮定すると、 レプリカの容量を測定するためのアルゴリズムを定義し、各レプリカの容量を確かめるためにベンチマークを実行する。

次の段階は、システムがN+1であるか、あるいは望ましい状態かどうかを決定するためにシステムを監視することである。

システムが利用率を監視するだけでなく、システムがコンプライアンスに従っていない時に運用チームに警告し、システムがその状態に近付いた時にもチームに警告する。理想的には、容量を追加するのにT分掛かる場合、システムは容量が必要となる少なくともT分前に警告を送る必要がある。

AWS(Amazon Web Services)のようなクラウドコンピューティングシステムは、必要に応じて容量を追加できるシステムである。独自のハードウェアで動作する場合、新しい容量のプロビジョニングは数週間あるいは数カ月掛かるかも知れない。いつも容量の追加を発注するのにCFOの許可が必要なら、あなたが考えるダイナミックでペースの速いハイテクの世界に生きていないことになる。

まとめ

誰でもロードバランサを利用できる。それを適切に使うのははるかに難しい。いくつかの疑問:

  1. このロードバランサは容量を増やすためか(N+0)、レジリエンシーを改善するために(N+1)利用するのか?

  2. どのように各レプリカの容量を測定するか? ベンチマーク入力をどのように作成するか? どのように合格と不合格の間の閾値に達するベンチマーク結果を処理するか?

  3. N+M設定に準拠するかどうかを監視しているか? あなたは仕様を維持するために容量を追加するのに十分な時間を提供できるよう警告をしているか?

これらの疑問に対する答えが「分からない」あるいは「いいえ」の場合、あなたは間違ったことを行なっている。

トーマス・A・リモンセリは、ニューヨーク市のStack Overflow社のサイト信頼性エンジニアである。彼の著書には「クラウド管理の実践」(http://the-cloud-book.com)、「システムとネットワーク管理の実践」(http://the-sysadmin-book.com)、「システム管理者のための時間管理」などがある。彼は、EverythingSysadmin.comでブログや、@YesThatTomでツイートを発信している。彼はドリュー大学でコンピュータサイエンスの学士を持っている。

関係する論文


The Tail at Scale
Jeffrey Dean, Luiz André Barroso
反応が早い大規模ウェブサービスを構築するために不可欠な遅延変動に耐えうるソフトウェア技術。
Communications of the ACM 56(2): 74-80
http://cacm.acm.org/magazines/2013/2/160173-the-tail-at-scale/abstract

Resilience Engineering: Learning to Embrace Failure
Jesse Robbins、Kripa Krishnan、John Allspaw、Tom Limoncelliとの議論
http://queue.acm.org/detail.cfm?id=2371297

The Pathologies of Big Data
Adam Jacobs
データセットを十分に拡大すると、全てのアプリが失敗する。典型的な問題は何か? そして、一般的にボトルネックはどこに現れるか?
http://queue.acm.org/detail.cfm?id=1563874 Copyright © 2016 held by owner/author. Publication rights licensed to ACM.

Hacker News