通信の負荷の分散

みなさんは、たくさんの人から異なる仕事を同時に急ぎでやってくれと言われたらどうなりますか？
それがあなたのキャパを超えるようなものだった場合、どのように対処するでしょうか。

有効な対策のひとつが、「応援を頼む」です。
これが「負荷の分散」です。

--------
・DNSラウンドロビン
たとえば、Webサーバがあるとしましょう。
業績があがってきて、サーバの負荷が増大してきたとします。
Webサーバを追加しました。

それぞれ、ホスト名を「www1」と「www2」としましょう。
でも、クライアントは「www.hogehoge.co.jp」というリクエストを送信してきます。
DNSサーバにwwwというホストのIPアドレスはこれですよ、という設定をしてあるからいままでは1台のWebサーバにリクエストが到達できていました。
これを、「wwwというホストのIPアドレスはこれとこれ（2つ）ありますよ」という設定をします。
そうするとDNSサーバはリクエストが来るたびに順番にwww1とwww2のIPアドレスを返すようになります。
これを「DNSラウンドロビン」と呼称します。

これで負荷が分散されましたが問題があります。
それは、DNSラウンとロビンでは死活監視を行わない、という点です。

仮にwww1がダウンしていたとしてもDNSサーバは順番にwww2のIPアドレスを返した次のリクエストではwww1のIPアドレスを返します。
よって、リクエストの半分は応答がなくなります。


------
・負荷分散装置（ロードバランサ=LB）の導入

そこで負荷分散装置という装置を導入します。
ここではwww1とwww2に対してVIP（VirtualIP）というIPアドレスを振ります。もちろんそれぞれのホストには本来のIPアドレスも付与されています。

DNSサーバにはwwwのIPアドレス問い合わせにはこのVIPを返すように設定します。
NATテーブルを修正してwwwのIPアドレスをLBのIPアドレスへ流すよう設定します。
次にFWでもフィルタ設定を変更し、LBのみhttp/https通信を許可します。

この負荷分散装置は配下に収まっているwww1とwww2の死活監視を行っていますので仮に1台がダウンしていてもサービスの継続が可能です。
この死活監視を行う通信をハートビートと呼ぶことがあります。
（もともとはクラスタリングで使用される言葉です。）

つまり負荷分散装置は冗長性も兼ね備えているということですね。

この負荷分散装置にも、いろいろな設定があります。

------
負荷分散といういうからには、負荷の軽いほうのサーバにリクエストを流すようにしますね。

では、なにを持ってリクエストを振り分けるかという設定があります。

まずひとつは、ラウンドロビンですね
これはDNSラウンドロビンと同じように順番にリクエストを割り振ります。
ただ、死活監視はしていますのでホストがダウンしていればそこへはリクエストは流しません。

次に優先度をあらかじめ設定しておく方法です。
旧サーバと新サーバだと性能が違うこともしばしばあります。
どちらのサーバに何割程度リクエストを流すのかを決めることができます。

現時点での接続数が少ない方を選択する方法もあります。
このあたりからちょっと賢くなってきますね。

応答時間を確認し、最も速く応答できるホストを選択させる方法、
CPU使用率で判断する方法もあります。

また、最初は1台目にすべてのリクエストを流すが、あらかじめ設定した負荷率（CPU使用率、接続数、応答時間）を超えるともう1台に割り振るという機能を持った負荷分散装置もあります。

------
Webアプリケーションなどを開発するお仕事のかたはここで少し不安になった方もいるのではないでしょうか。

それは、「セッション維持はどうするの」という部分ですね。
1度目のアクセス時にwww1に接続し、そこで応答を返す。
もう一度アクセスした際にwww2につながったら、Webアプリケーションが正しく動作しなくなるという不安がよぎったかたもいるかも知れません。

ご心配いりません。
Cookieに識別IDがあるので（載せるよう設計してください）それでwww1で処理したリクエストはもう一度アクセスした際にはまたwww1へ流されます。

SSLのセッションIDも同様です。

------
リバースプロキシ

リバースプロキシをこのトピックで扱うことには少し抵抗があるのですけど、負荷分散というよりは負荷軽減という意味で紹介しておきます。

リバースプロキシの前にまずプロキシを説明します。

みなさんのPCの設定で、企業内で使用しているものについては設定されていることも多いと思いますが、各PC上で設定する項目になります。

Webアクセスを行う際に、直接インターネットに出ていくのではなく、プロキシサーバというサーバを指定する方法です。
このプロキシサーバがみなさんのPCの代わりにリクエストを送るわけです。

その結果、セキュリティに問題があったり、また社内ルール上問題のあるサイトと判断した場合にアクセスさせないといった挙動をさせることも可能です。（フィルタリング機能）

もっとも大きな機能は、こうして取得したデータを一定期間プロキシサーバにためておき（キャッシング）、次に同じリクエストがあった場合にそのキャッシュを見させることで、Webアクセスを減らすことができるようものです。


それを利用したリバースプロキシについて説明しましょう。

サーバ側に視点を変えると外部から自社のWebサーバに対してリクエストが次々に来るとしてください。
このリクエストが同じリクエストであった場合にWebサーバのかわりにキャッシュしたデータをクライアントに返してくれるのがリバースプロキシです。

またFWの内側にLAN2つを積んだリバースプロキシを設置し、違うネットワーク上にWebサーバを設置することで攻撃者からWebサーバを隠すような形態も考えれますね。

このプロキシによく似た動作をするものでCDN（コンテンツデリバリーネットワーク）というものもあります。
キャッシュサーバと呼ばれるサーバを配置してコンテンツを配信します。
サーバへリクエストが到達するとキャッシュサーバへリクエストをリダイレクトするような仕組みがあります。

動作は似ていますがプロキシとは別のものとなります。

で、これらキャッシュを使用したものには共通の問題があります。
それは、「取得したコンテンツが最新でない場合がある」という点です。

これに対しては、DNSやCookieのTTL(Time To Live=生存期間)を調整することで対応しているようですが、なかなか最適値を出すのは難しいでしょうね。


------
SSLアクセラレータ

こちらも負荷分散というよりは負荷軽減のための装置ではあるのですが、ついでに触れておきましょう。

昨今、httpはすっかりと使われなくなりもっぱらhttpsでなければ信用されない時代となりました。
httpsで通信するにはSSLが必要になるわけですが、サーバにとってSSLの通信処理には膨大な性能が必要となります。

そこでSSLの処理をWebサーバのかわりに受け持つのがSSLアクセラレータというわけです。
アプライアンス型もあれば、カード型でサーバに差し込む方式のものもあるようです。（おおくはアプライアンス型でしょう）

このSSLアクセラレータも、大変な処理を肩代わりしているということで同時接続数上限を設定しているものがあります。
その閾値を超えた場合、次のリクエストはカスケード接続されたほかのSSLアクセラレータへ流されます。
このようにWebサーバではなくてSSLアクセラレータ自体を負荷分散することもあるというのも覚えておくといいかもしれません。

SSLアクセラレータで復号化された通信は、とうぜん暗号化されていないことにもt留意が必要です。

------
ロードバランサとSSLアクセラレータを組み合わせるやり方もあります。

が、ここでちょっと考慮すべき部分があります。
セッション維持のためにCookieを使用するという話を上述しました。

ところがSSLで通信している場合、このCookieも暗号化されています。
そうすると負荷分散装置はセッション維持が出来ません。

ロードバランサをSSLアクセラレータのうしろ、Webサーバとアクセラレータの間に配置することで解決します。

SSLのセッションIDを使用して負荷分散させる場合は考慮の必要はありません。
SSLではセッションIDは暗号化されません。

このように、各機器の配置には熟慮が必要です。