node.jsを使うとサーバーリソースを抑えられるという。どういう仕組みなのだろうか。

 PHPやPerl、Ruby、Javaといった言語で開発した一般的なWebシステムの場合、アクセス数が増えるほど必要とするサーバーのメモリー容量が増える。処理要求を受け付けるごとにプロセスやスレッドを生成するからだ。多数のプロセスやスレッドを並列処理させることで、集中する処理要求をさばく仕組みになっている。

 node.jsの仕組みは上記と大きく異なり、1コアに1個のプロセス、スレッドで動作する「シングルスレッド」である。だからサーバーのメモリーは少なくて済むのだ。しかし普通に考えれば、シングルスレッドではリクエスト処理が追いつかず、処理待ちが多くなってしまう。node.jsはそうならないように、「非同期I/O処理」という仕組みが備わっている。

 ここでいうI/O処理とは、ファイルの読み書き、データベースの読み書き、ネットワークを使ったデータのやり取りなどのことである。I/O処理を実行するのは、アプリケーション部分ではなくOSである。通常は同期I/O処理で、OSが実行しているI/O処理が完了するのを待って次の処理を実行する。それに対して非同期I/O処理は、OSが実行しているI/O処理の完了を待たずに次の処理を実行する。node.jsは、OSがI/O処理を完了したかどうかを逐次監視し、完了した時点でレスポンスを返す。

 図1は同期I/O処理と非同期I/O処理を比較したものである。二つのWebブラウザー(A、B)からほぼ同時にリクエストが来た場面を想定している。同期I/O処理はAのリクエストの処理が終了するのを待ってBの処理が始まるが、非同期I/O処理ではAの処理の終了を待たずにBの処理が始まる。非同期I/O処理の方が効率がいいのが分かるだろう。

図1●同期I/O処理と非同期I/O処理の違い
図1●同期I/O処理と非同期I/O処理の違い
複数のリクエストをほぼ同時に受け取った場合、非同期I/O処理の方が待ち時間が短くなる
[画像のクリックで拡大表示]