MS_NLB - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

NLB

概要

サービスの「負荷分散・拡張性」・「冗長性・可用性」の向上を図るためのサービス

  • ステートレス・システムの負荷分散が可能。
  • 負荷分散装置等のフロントのアプライアンスが不要。

移行メモ(正式名称): NLB = Network Load Balancing
(ネットワーク負荷分散)。Windows Server の機能の一つで、
追加のハードウェアなしにサーバー群を負荷分散できる。

特徴

  • 各構成ノードは、仮想的なネットワークカードを持つ。

    • 各ノードのネットワークカードは、NLB グループ毎に同一の MAC アドレスを持ち、
      クライアントは NLB の各ノードを区別できない。
    • 仮想ネットワークカードは、受信した TCP/IP ネットワーク・トラフィックを
      均等に分散させたり、重み付けして分散させたりすることができる。
    • リクエストを自ノードで処理するべきと判断した場合、
      NLB はデータ・パケットを上位層へ送る。
  • NLB は、各構成ノードを常に監視しており、

    • 障害を起こしたサーバは自動的に NLB から離脱する。
    • また、サーバが復帰した時は自動的に NLB に復帰する。
    • この作業はクラスタよりも迅速に動作する。

補足(監視の粒度に注意): 「各構成ノードを常に監視」しているのは
ハートビート(ノードの生死) であって、
アプリケーションの健全性ではない

つまり、IIS が 500 を返し続けていても、
OS が生きていれば NLB はそのノードへ振り分け続ける。
ロードバランサ製品にあるヘルスチェック(URL 監視)に相当する機能は無い
これは NLB を採用する際の最大の制約であり、
実務では別途プロセス監視を組む必要がある。

適合するシステム

  • ステートレスなシステム
  • データの更新があまり発生しないシステム(コンテンツの手動更新のレベル)

方式

要約していうと、

  • 複数のサーバに共通の仮想 IP・MAC アドレスを持たせクラスタを構成する。
  • クライアントからは単一の IP アドレスとコンピュータ名を持つシステムに見える。

処理の振り分け方式は、

という方式である。

(ハッシュ関数の再構築による)フェイル・オーバーも可能になっている。

補足(この方式の本質): NLB には
「振り分ける装置」が存在しないという点が最大の特徴である。

  1. パケットは全ノードに届く(同じ MAC アドレスなので)。
  2. 各ノードが自分で計算して「これは自分が処理すべきか」を判断する。
  3. 担当でないノードは、上位層に渡さず破棄する。

単一障害点が無いという利点の裏返しとして、

  • 全ノードが全トラフィックを受信する(帯域の無駄)
  • スイッチ側でフラッディングが発生する(後述のモード次第)

という代償がある。ノード数が増えるほど効率が落ちるため、
大規模構成には向かない。

IPアドレス

「仮想サーバ」を構成する NIC には、

  • 「専用 IP アドレス」
  • 「仮想 IP アドレス」

の設定が必要。

専用IPアドレス

「物理サーバ」のデータ送受信に利用される。

仮想IPアドレス

「仮想サーバ」のデータ送受信に利用される。

ハッシュ関数によるパーシステンス

上記の分散処理方式を実現するため、
NLB のハッシュ関数は、パーシステンス(セッション維持)方式として、

  • ロードバランサ - パーシステンスの種類
    http://www.infraexpert.com/study/loadbalancer5.html
    • Source address affinity persistence
    • Cookie persistence
    • SSL persistence
    • Destination address affinity persistence
    • Hash persistence
    • SIP persistence
    • Universal persistence
    • Microsoft Remote Desktop Protocol persistence

のうち Source address affinity persistence を採用している。

プロトコル

がある。

分散処理方式

分散処理方式に

  • ユニキャスト・モード
  • マルチキャスト・モード

が存在する。

ユニキャスト・モード

  • サーバの物理ノードに同じ IP アドレス(MAC アドレス)を付与し、
  • 全ての物理ノードでパケットを受信。
  • 次いで、ハッシュ関数を使用して要求フィルタする。

マルチキャスト・モード

  • サーバの物理ノードに異なる IP アドレスを付与し、
  • マルチ・キャストを使用して全ての物理ノードでパケットを受信。
  • 次いで、ハッシュ関数を使用して要求フィルタする。

ハッシュ関数によるパーシステンス

Source address affinity persistence の affinity として、
下記の2つのアフィニティが存在する。

アフィニティ

単一モード

単一モードのハッシュ関数は、クライアントの IP アドレスから物理ノードを選択する。

  • クライアントは、常に同じノードに振り分けられる。
  • プロキシサーバーを経由すると、偏りが発生することがある。

なしモード

なしモードのハッシュ関数は、クライアントの IP アドレス+ポートから
物理ノードを選択する。

∴ クライアントの TCP/IP 接続が異なると、異なるノードに振り分けられる。

移行メモ(正誤): 元ページは「クライアントの IP アドレスから
物理ノードが選択する」と書いているが、主語が逆で、
ハッシュ関数が物理ノードを選択するである。上記のとおり訂正した。

補足(実務での既定と落とし穴): 「単一モード」(アフィニティ = 単一)が
既定であり、ほぼこれを使う。ただし次に注意が要る。

事象 原因
特定ノードに偏る 大企業・キャリアのプロキシ / NAT で、多数の利用者が同一送信元 IP に見える
セッションが飛ぶ ノード追加・削除時の「収束」でハッシュが再構成され、割り当てが変わる
モバイル回線で切れる 回線切替で送信元 IP が変わる

3 番目は「なしモード」でも解決しない。
結局、セッションをサーバー外に出す(後述の「その他」)のが
唯一の確実な対処である。

フェイルオーバー

「仮想サーバ」を構成する NIC は、互いの動作を調整するために
クラスタ内で定期的に「ハート ビート」を交換している。

  • 「仮想サーバ」を構成する「物理サーバ」で障害が発生したり、
    「物理サーバ」が追加・削除されたりして、「ハート ビート」に変化が生じた場合、
    NLB はクラスタ構成の変更を検出し「収束」と呼ばれるプロセスを開始する。

  • 「収束」プロセスでは、「仮想サーバ」を構成する「物理サーバ」間で
    メッセージが交換され、入力トラフィックをフィルタするハッシュ テーブルを
    再生成し、「物理サーバ」間に展開・共有する。

  • これにより「仮想サーバ」が再構築され、
    クライアント要求は「物理サーバ」に再分散される。

操作モードとNIC枚数

ユニキャスト・モード

NIC1枚

  • 長所

    • 1枚の NIC でも動作する
    • 全てのルータで機能する
  • 短所

    • 負荷によっては、2 枚目の NIC が必要
    • クラスタ ホスト間の通信は不可能
      ※ ユニキャスト・モードでは、「仮想サーバ」を構成する全ての NIC に
      同じ MAC アドレスを割り当てるため、これら NIC 間での通信ができない。

NIC2枚以上

  • 長所

    • 全てのルータで機能する
    • クラスタ ホスト間の通信が可能
    • トラフィックの分離により、全体的な性能が向上する
      • フロントエンド、バックエンドとの通信の分離
      • 管理操作の分離
  • 短所

    • 2枚以上の NIC が必要

マルチキャスト・モード

NIC1枚

  • 長所

    • 1枚の NIC でも動作する
    • クラスタ ホスト間の通信が可能
  • 短所

    • 負荷によっては、2枚目の NIC が必要
    • ルータによっては特別な設定が必要

NIC2枚以上

  • 長所

    • クラスタ ホスト間の通信が可能
    • トラフィックの分離により、全体的な性能が向上する
      • フロントエンド、バックエンドとの通信の分離
      • 管理操作の分離
  • 短所

    • 2枚以上の NIC が必要
    • ルータによっては特別な設定が必要

補足(「ルータによっては特別な設定が必要」の中身): マルチキャスト・モードでは、
ユニキャスト IP に対してマルチキャスト MAC を応答するという
RFC 的に変則的な ARP を返す。
このため多くのルータ / L3 スイッチが応答を破棄してしまい、
静的 ARP エントリの登録が必要になる。

ユニキャスト・モードにも別の問題があり、
全ノードが同一 MAC を名乗るためスイッチの MAC アドレス テーブルが
学習できず、全ポートへのフラッディングが起きる。
セグメント全体の帯域を圧迫するため、
NLB は専用の VLAN に隔離するのが定石である。

その他

ASP.NETでは、SessionState を使用するステートフルな
アプリケーションでも、ステートサーバや SQL Server
状態を一時退避する事で、以下を可能にしている。

  • [なしモード]での負荷分散([単一モード]なら不要)
  • [単一モード]でフェイル・オーバした後の業務続行(不可能なら不要)
  • ただし、ステートサーバや SQL Server はシングル・ポイントになり得る。

補足(現在の選択肢): 「ステートをサーバー外へ」という考え方は今も正しいが、
受け皿は変わった。

世代 セッション ストア
.NET Framework 時代 ASP.NET State Service / SQL Server
現在(ASP.NET Core Redis / SQL Server / 分散メモリ キャッシュ

より根本的には、セッションを持たない(トークンベースにする)
設計にすれば負荷分散の制約が消える。
JWTを使う構成が広く採られているのはこのためである。

補足(NLB を今から選ぶべきか): NLB は
「追加コストなしで済む」点が最大の利点だが、

  • アプリケーション レベルのヘルスチェックが無い
  • L7 の振り分け(URL パス・ヘッダー)ができない
  • SSL 終端ができない
  • ノード数が増えると効率が落ちる

という制約がある。
オンプレでも Nginx / HAProxy、クラウドなら
Azure Load Balancer / Application Gateway を使う方が、
運用も含めて素直である。
既存資産の理解として本ページを読むのが実務的な位置づけになる。

参考


Tags: 移行, Windows, 冗長化

⚠️ **GitHub.com Fallback** ⚠️