next up previous contents
Next: 1.3 nginxの思想 Up: 1. Nginxの概要 Previous: 1.1 Nginxとは

1.2 Nginxのアーキテクチャ

サーバクライアントモデルにおけるサーバプログラムには、基本的に2つの種類が あります。古くは、fork型と言われ、今風にはプロセス駆動型と呼ばれる方式で、 今一つは select型、現代風にはイベント駆動型と呼ばれる方式です。 fork型は、簡単に言えば、一つのクライアントに対応できるようなサーバを 作り、そのサーバに自分自身を増殖させる(forkと言います)機能を追加して、 多数のクライアントに対応させます。一方、select型は、最初から多くの クライアントに対応できる構造ですが、窓口は一つであるために行列ができる 方式です。fork型は、その構造上、つきっきりでクライアントに対応するので、 相手を待たせません。また、自信の分身を作る際に速度が遅くなる傾向がある ので、Apache などは予め先に自分の分身を作っておく方式(prefork)を取ること で、分身を作ることによる時間ロスをなくしています。一般に、forkするか selectするかは、サーバのタイプによって選択されることが多いようです。 例えば、forkすると、分身の前の記憶は共有されますが、分身した後は、 記憶は共有されません。このために、それぞれの分身が独立して動いても 構わないようなサーバに多く利用されます。一方、select型は、元々一つなので、 記憶が共有されています。そこで、チャットプログラムや、映像共有などの アプリケーションに向いているとされています。

このように、サーバの型はその用途によって選択されていたのですが、 Webサーバは非常に特殊で、多くのアクセスが一度にあるような場合、 fork型だとメモリを大量に消費することになります。勿論、無限には ないので、結局は分身の数を制限せざるを得ず、このために資源を浪費し、 多くのクライアントに対応できない結果となってしまう訳です。 一方、select型は、一つのプログラムで多くのクライアントに対応する ために、うまく一つ一つのクライアントの処理をループで回すことが 出来れば、数が増えてもfork型のような浪費をしないために、比較的に スケールアップに対応しやすい訳です。このように nginx は、こうした 問題に対応するために select 型でわざと開発がされたサーバである 訳ですが、当然問題もあり、多数のアクセスがある場合の対応速度は どうしても遅くなりがちです。この辺りは、イベント処理をうまく やることで高速性を維持しているようですが、それでもCMSのような 重い処理を nginx に行わせると苦しいようです。このために、フロント エンドを nginx で動かし、バックエンドを Apache にした上で、 ロードバランスなどを組み合わせることで数と量をこなすように工夫して 居る場合もあるようです。

参考
一般に、情報の世界では、速度と資源はトレードオフの関係に あると言われています。速さを求めると資源を浪費し、資源を節約すると 速度が落ちる傾向にあります。どちらを重視して、どの程度で折り合うか という問題は非常に普遍的な問題で、ケースバイケースな問題だと言って 良いでしょう。

実は、nginx も全く fork を使ってない訳ではありません。nginx では、 CPU資源を最適化するために、通常はコアの数程度のワーカーと呼ばれる 分身を作り、ワーカーの内部では select を利用して、多数のクライアント に対応するような処理を行っています。

Apacheの反撃
Apache 2.4 では、MPM が標準化されています。この MPM は、Apacheでもワーカーやスレッド化されたイベント処理が可能になって いますが、まだ十分にはチューニングされていないようです。しかし、 チューニングを施すと、nginx に匹敵するほどのパフォーマンスを発揮 出来る場合があるようです。



Noriyo Kanayama