web-dev-qa-db-ja.com

Node.jsがApacheよりもスケーラブルな理由は何ですか?

正直に言うと、私はまだ完全には理解していません。そして、イベントモデルを使用する単一のスレッドとして、Node.jsがどのように機能するかさえ理解しています。これがApacheよりも優れているか、シングルスレッドの場合に水平方向にどのようにスケーリングするかはわかりません。

73
MaiaVictor

Tomislav Capanによるこのブログ投稿は非常によく説明していることがわかりました。
地獄がNode.jsを使用する理由?ケースバイケースの紹介

Node 0.10、Apacheと比較して)の要点の私の解釈:

良い部分

  • Node.jsは、リクエストごとにスレッドのスピンアップを回避します。ま​​たは、Apacheのように一連のスレッドへのリクエストのプーリングを処理する必要はありません。したがって、リクエストを処理するためのオーバーヘッドが少なく、迅速な応答が得られます。
  • Node.jsは、requestの実行を別のコンポーネントに委任し、委任されたコンポーネントが処理された結果で戻るまで、新しい要求に集中できます。これは非同期コードであり、イベントモデルによって可能になります。 Apacheはプール内でリクエストをシリアルで実行し、モジュールの1つがタスクの完了を単に待機している場合、スレッドを再利用できません。 Apacheは、プール内のスレッドが再び利用可能になるまでリクエストをキューに入れます。
  • Node.jsはJavaScriptと通信するため、MongoDBなどの外部Web APIソースから取得したJSONの通過と操作が非常に高速であり、リクエストごとに必要な時間を短縮します。 PHPのようなApacheモジュールは、データを処理するために マーシャリング を必要とするため、JSONを効率的に解析および操作できないため、より多くの時間が必要になる場合があります。

悪い部分

注:以下にリストされている不良部分のほとんどは、今後のバージョン0.12で改善される予定です。

  • Node.jsは、計算が集中するタスクを吸い込みます。これは、長時間実行されるたびに、シングルスレッドのために他のすべての着信要求をキューに入れるためです。一般に、Apacheはより多くのスレッドを使用でき、OSはこれらのスレッド間のCPU時間をきちんと公平にスケジュールしますが、少し遅くなりますが、新しいスレッドを処理できます。 Apacheで利用可能なすべてのスレッドがリクエストを処理している場合を除き、Apacheはリクエストのキューイングも開始します。
  • Node.jsは、Node.jsクラスターを作成するか、子プロセスをスピンアップしない限り、マルチコアCPUを完全には利用しません。皮肉なことに、後者の2つを行うと、Apacheと同じ問題であるオーケストレーションのオーバーヘッドをさらに追加する可能性があります。論理的には、Node.jsプロセスをさらに起動することもできますが、これはNode.jsによって管理されません。コードをテストして、より効果的なものを確認する必要があります。 1)クラスタと子プロセスを使用したNode.js内からのマルチスレッド、または2)複数のNode.jsプロセス。

緩和策

すべてのサーバープラットフォームには上限があります。 Node.jsとApacheの両方が何らかの時点でそれに到達します。

  • Node.jsは、重い計算タスクがある場合に最速で到達します。
  • 長いシリアル実行を必要とする大量の小さなリクエストを投げると、Apacheは最も速く到達します。

Node.jsのスループットをスケーリングするためにできる3つのこと

  1. cluster を設定するか、 子プロセス を使用するか、マルチコアCPUを使用するか、または Phusion Passenger のようなマルチプロセスオーケストレーターを使用します。
  2. メッセージキューに接続されたワーカーロールをセットアップします。これは、計算集約的な長時間実行要求に対する最も効果的なソリューションです。それらをワーカーファームにオフロードします。これにより、サーバーが2つの部分に分割されます。 1)ユーザーからのリクエストを受け付ける一般向けの事務用サーバー、および2)長時間実行されるタスクを処理するプライベートワーカーサーバー。両方ともメッセージキューで接続されています。事務用サーバーは、メッセージ(長時間実行される着信要求)をキューに追加します。ワーカーロールは着信メッセージをリッスンし、それらを処理し、結果をメッセージキューに返す場合があります。要求/応答が必要な場合、事務サーバは、応答メッセージがメッセージキューに到着するのを非同期に待つことができます。メッセージキューの例は RabbitMQ および ZeroMQ です。
  3. ロードバランサーを設定し、より多くのサーバーをスピンアップします。これで、ハードウェアを効率的に使用し、長時間実行されるタスクを委任したので、水平方向に拡張できます。ロードバランサーがある場合は、事務用サーバーを追加できます。メッセージキューを使用して、ワーカーサーバーを追加できます。オンデマンドで拡張できるように、クラウドでこれを設定することもできます。
88
Bart Verkoeijen

どのように使用するかによります。 Node.jsはデフォルトでシングルスレッドですが、(比較的)新しいクラスターモジュールを使用すると、複数のスレッドに水平にスケーリングできます。

さらに、データベースのニーズにより、ノードでのスケーリングの効果が決まります。たとえば、node.jsでMySQLを使用しても、MongoDBとnode.jsの両方がイベント駆動型であるため、MongoDBを使用した場合ほど多くの利点は得られません。

次のリンクには、さまざまなセットアップのシステムの多くのNiceベンチマークがあります。 http://www.techempower.com/benchmarks/

Node.jsは最高ランクではありませんが、nginxを使用した他のセットアップ(テーブル上にApacheはありませんが、十分に近い)と比較すると、かなり良好です。

繰り返しますが、それはあなたのニーズに大きく依存します。単純に静的なWebサイトを提供している場合は、従来のスタックを使用することをお勧めします。しかし、人々は他のニーズのためにnode.jsでいくつかの驚くべきことをしました: http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/ (c10k ?ha!)

編集:あなたが本当にApacheだけをnode.jsで「置き換える」のではないことを言及する価値があります。 Apacheとphp(典型的なランプスタック内)を置き換えることになります。

38
Kevin Lee