IT の基礎

ロードバランシングの基礎

ロードバランサは、1 つの入口で受けたリクエストを複数のサーバーへ分け、応答しなくなったサーバーをヘルスチェックで自動的に外します。HTTP の中身まで見て振り分けるのが L7、IP アドレスとポートだけで振り分けるのが L4 です。

ロードバランサは、利用者からのリクエストを 1 つの入口で受け、後ろに並べた複数のサーバーへ分けて渡す仕組みです。目的は 2 つあります。1 台では処理しきれない量を分けること (負荷分散) と、1 台が壊れても残りで受け続けることです。壊れたサーバーを見つけるのがヘルスチェック、どこまで中身を見て振り分けるかの違いが L4 と L7 です。Google Cloud でどのロードバランサを選ぶかはネットワークの設計で扱い、このページではその前提になる仕組みを見ます。

入口を 1 つにして、後ろのサーバーを入れ替えられるようにする

利用者が知っているのはロードバランサの IP アドレスだけです。後ろのサーバー (バックエンドと呼びます) を増やしても減らしても、利用者の側は何も変えずに済みます。

利用者ロードバランサIP は 1 つサーバー 1サーバー 2サーバー 3応答なし外した
利用者が見るのはロードバランサの IP だけ。応答しないサーバー 3 は外れ、残りの 2 台が受け続ける

この形にすると、アクセスが増えたらサーバーを足し、メンテナンスのときは 1 台ずつ外して作業できます。Google Cloud のマネージドインスタンスグループのように、負荷に合わせて VM の台数を自動で増減する仕組みも、ロードバランサが入口を引き受けているから成り立ちます。

振り分けの方式は、サーバーの状態を見るかどうかで分かれる

次にどのサーバーへ送るかを決める規則を、振り分けの方式 (アルゴリズム) と呼びます。代表的なものは次の 3 つです。

方式決め方向く場面
ラウンドロビン1 台目、2 台目、3 台目と順番に回すサーバーの性能と 1 件の重さがそろっている
最小接続いま処理中の件数が一番少ないサーバーを選ぶ処理時間が件数ごとにばらつく
ハッシュ送信元 IP アドレスなどから計算し、同じ利用者を同じサーバーへ送るログイン状態をサーバーが覚えている

ラウンドロビンは、遅いサーバーにも同じ数を送るので、そのサーバーにだけ処理待ちがたまります。最小接続は処理中の件数を見るため、遅いサーバーへ送る数が自然に減ります。同じ利用者を同じサーバーへ送り続ける設定をセッションアフィニティと呼びます。

Google Cloud では、プロキシ型のロードバランサの既定がラウンドロビン (ROUND_ROBIN) です。処理中のリクエストが少ないほうを選ぶ LEAST_REQUEST や、ハッシュで送り先を固定する RING_HASH などにも変えられます (バックエンドサービスの説明)。

ヘルスチェックが失敗し続けたサーバーを外す

ヘルスチェックは、ロードバランサの側から各サーバーへ一定の間隔で問い合わせ、応答が返るかを確かめる仕組みです。Google Cloud のヘルスチェックの既定値は、間隔 5 秒、応答を待つ時間 5 秒です。2 回続けて失敗すると異常とみなして新しい接続を送らなくなり、2 回続けて成功すると正常に戻します。

確認 1失敗 1/2確認 2失敗 2/2外れた残りへ送る停止0 秒5 秒10 秒15 秒この間は失敗する
止まってから外れるまでの約 8 秒間は、そのサーバーに送ったリクエストが失敗する

止まってから外れるまでの時間は、おおよそ「間隔 × 失敗の回数」で決まります。早く外したいなら間隔を短くするか回数を減らしますが、一瞬の遅れで正常なサーバーまで外れやすくなります。すべてのサーバーが外れると振り分け先がなくなり、Google Cloud のアプリケーションロードバランサは HTTP の 503 を返します。

ヘルスチェックの問い合わせは Google の決まったアドレス範囲 (たとえば 35.191.0.0/16) から届きます。この範囲をファイアウォールで許可し忘れると、サーバーは動いているのに全台が異常と判定されます。

L4 は宛先の番号だけを、L7 は HTTP の中身を見る

L4、L7 の「L」は通信の層 (レイヤー) のことです。L4 は TCP や UDP の層で、見えるのは IP アドレスとポート番号だけです。L7 はアプリケーションの層で、HTTP のパス (/api/users の部分)、ホスト名、ヘッダーまで読めます。

L4: IP とポートだけを見るパケット宛先ポート 443L4 LBweb 群L7: HTTP の中身を見るリクエストGET /api/usersL7 LBapi 群web 群/api/*それ以外
パスで送り先を変えられるのは L7 だけ。L4 は中身を読まずに速く転送する

L7 のロードバランサは、利用者との通信をいったん自分で受けて終わらせ (終端し)、HTTPS の暗号を解いてから中身を読みます。その分、パスごとに別のサーバー群へ送る、証明書をロードバランサで一括管理する、といった処理ができます。L4 は中身を読まないので、HTTP 以外の通信 (ゲームの UDP、データベースの TCP など) も扱えます。

Google Cloud では、L7 がアプリケーションロードバランサ、L4 がネットワークロードバランサです。アプリケーションロードバランサでは、パスと送り先の対応を URL マップに書きます。たとえば /video/* というパスのルールは /video/test1 に一致し、/video そのものには一致しません (URL マップの説明)。

シミュレーター

台数と方式を選んでリクエストを流し、サーバーを止めてみてください。1 回の送信を 5 秒とし、送るたびにヘルスチェックが 1 回走ります。止めた直後の 2 回は失敗が出て、その後に外れることを確かめられます。L7 に切り替えると、パスのルールで api 群へ送る件を分けられます。

試すロードバランサの振り分けとヘルスチェック

ロードバランサが見るもの
振り分けの方式
3 台
サーバーを止める

経過 0 秒 / ヘルスチェック 0 回

  • web-1正常・振り分け対象今回 0 件 / 累計 0 件
  • web-2正常・振り分け対象今回 0 件 / 累計 0 件
  • web-3正常・振り分け対象今回 0 件 / 累計 0 件

「リクエストを 6 件送る」を押すと、ロードバランサが 1 件ずつ振り分け先を選びます。そのあと 5 秒ごとのヘルスチェックが 1 回走ります。

試験では

PCA の問題文に「HTTP(S)」「パスで振り分ける」「証明書」「Cloud Armor」と出たら L7、「UDP」「送信元 IP をそのまま」「HTTP 以外の TCP」と出たら L4 を考えます。「1 台が落ちてもサービスを止めない」という要件は、複数台のサーバーをロードバランサの後ろに置き、ヘルスチェックで外す構成で満たします。種類の選び方はネットワークの設計、複数ゾーンにまたがる冗長化は信頼性と災害復旧で扱います。

理解度チェック

答えを開く前に、自分で考えてください。結果はこのブラウザにだけ残り、間違えた問題は復習のページでまとめて解き直せます。

思い出す

Google Cloud のヘルスチェックの既定値 (間隔 5 秒、2 回続けて失敗で異常) のとき、サーバーが止まってから振り分け先から外れるまでの間、そのサーバーに送ったリクエストはどうなりますか。

状況で選ぶ

1 つのドメインで、/api/users や /api/orders のような /api/ で始まるリクエストを API サーバー群へ、それ以外を Web サーバー群へ送りたいと考えています。HTTPS の証明書はロードバランサでまとめて管理したいです。どう構成しますか。

説明する

リクエストごとに処理時間が大きくばらつく API を、複数のサーバーで受けます。振り分けの方式にラウンドロビンと最小接続のどちらを選びますか。どちらでもよいのはどんな条件のときかも含めて説明してください。