キャッシュサーバーで大規模サイト構築

以前、お客様のご要望で、複数台の負荷分散で毎秒数千リクエスト、数ギガbpsのトラフィックを延々とさばくようなシステムを作るための試行錯誤を重ねておりました。
そのときの試行錯誤や最終的に落ち着いた方法についてまとめておくことにします。

やりたいことはこうです。

・画像や動画ダウンロードが主体のファイル置き場のサーバーを運営して膨大な数のリクエストに対応したい。

考慮するポイントは以下の通り
・動画は1本10MB程度~20MB。コンテンツの更新時にはこれが10本程度は増える。初期は全体で1.5TB程度。
・トラフィックは数ギガbpsになるので、1Gbps回線が複数必要。必要な本数を用意する。コストはかかってもよい。
・リクエストは毎秒1000以上はあるので、負荷分散は必須。マシンを複数台用意する。コストはかかってもよい。

考えられる方法は以下の通り
・DNSラウンドロビン
・ロードバランサー(専用機器)
・ロードバランサー(ソフトウェア)
・リバースプロキシ&キャッシュ兼ロードバランサー
またはこれらの併用。

最も単純な方法としては、DNSラウンドロビンがあります。
DNSラウンドロビンは特定のホスト名あるいはドメイン名を複数のサーバーに均等に負荷分散する仕組みです。
DNSラウンドロビンには「512バイト問題」があり、分散するサーバーが増えて大体10~15台以上くらいになってくると正常にラウンドロビンされなくなってきます。

専用機器のロードバランサー(L4スイッチ、L7スイッチ等)を導入する方法もありますが、サーバーの外側に専用機器を配備する構成の構築は当サービスの範疇外ですのでこの場合はお客様独自でやって頂くか他社に依頼してもらうことになります。
コスト面と専門性からいって、そこまでする必要があるかは検討の余地があります。

ソフトウェアロードバランサーとしては、LVS(Linux Virtual Server)や Nginx, Varnish, Pound などがありますが、当サービスでは Nginx, Varnish を扱っています。
Nginx, Varnish は、どちらもリバースプロキシ&キャッシュ兼ロードバランサーとして使えます。

今回はDNSラウンドロビンおよびリバースプロキシ&キャッシュ兼ロードバランサー構成を導入しました。

フロントエンドにリバースプロキシ&キャッシュサーバー複数台とバックエンドにストレージサーバー複数台という構成になります。
フロントエンドにミドルウェアとして Nginx を使うか Varnish を使うかで迷い、両方を試してみました。

Nginx と Varnish では、基本設定が簡単なのは Varnish です。
Varnish は、バーチャルホストの設定すら必要ありません。
Varnish は、OSのバッファリング機構を使って極力ファイルI/Oを減らすのでメモリがふんだんにあれば Nginx よりキビキビ動きますし、最適化もうまくやるのでチューニング要らずです。
ただし、ちょっとでも細いチューニングをしたくなったら Varnish では難しくなります。
Varnish は、専用言語のスクリプトで関数を組んで設定を行う仕様なので非常に扱いにくいです。
また、Varnish は、ログファイルを普通に出力することもできませんし。
また、使ってみると Varnish は、数百ギガバイトなどの大量のキャッシュを保持するには不向きだということがわかりました。ファイルI/Oが増えると Nginx よりもCPU負荷を食うようで耐えられるピークに達するのが早かったです。
Nginx と Varnish 両方使ってみて結局 Nginx で運用することにシフトしました。

次にフロントエンドとバックエンドの台数構成ですが、

一般には、1台のフロントエンド→複数台のバックエンド、そのセットを複数持つ形にします。
例えば、1台のフロントエンド→2台のバックエンドという形を3セットなら、フロントエンド3台はDNSラウンドロビンで、その先にローカル接続でバックエンド2台×3のドメインなしのサーバーを配置し、全体で合計9台です。
ところで、そうするとバックエンドのどれかをFTPサーバーとして、それ以外のバックエンドサーバーへコンテンツの同期が必要になります。
バックエンドの台数が増えれば増えるほど、一度にアップデートが多いほど同期に時間がかかります。

そこで発想を変えて、例えば極端な話、バックエンドは1台の非常に高スペックなサーバーを用意し、フロントエンドを5~6台用意するのはどうでしょう?
コンテンツの同期が不要になります。
平常時のアクセスに十分な程度フロントエンドにキャッシュし終わって、キャッシュヒットさえしていればバックエンドへはアクセスがないのだから、お客様(サイトオーナー)としてはバックエンドの台数が多いことがどうも無駄に思えてこんな発想をするようです。
でもこれだと、一番最初稼働し始めた時はバックエンドへのアクセス集中が持ち堪えられるかが大きな問題になります。
大量のコンテンツアップデートがあったときや、フロントエンドにサーバーを増やすときなども。
そんなとき、裏で手作業か何かの方法で1台だけキャッシュ構築をやって、HDDクローンしてキャッシュサーバーをアップデートするという方法もありますが、現実的では無い気がします。

やはりフロントエンド→バックエンドのツリー形状が妥当でしょう。
やはり先人の考えたオーソドックスな方法には意味があるのです。
結局その形に落ち着きました。

コメントを残す