27

以下が欲しい

  • 起動時に、マスター プロセスはファイルから大きなテーブルをロードし、それを共有変数に保存します。テーブルには 9 列と 1200 万行があり、サイズは 432MB です。
  • ワーカー プロセスは HTTP サーバーを実行し、大きなテーブルに対するリアルタイムのクエリを受け入れます。

これが私のコードですが、明らかに私の目標を達成していません。

var my_shared_var;
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Load a large table from file and save it into my_shared_var,
  // hoping the worker processes can access to this shared variable,
  // so that the worker processes do not need to reload the table from file.
  // The loading typically takes 15 seconds.
  my_shared_var = load('path_to_my_large_table');

  // Fork worker processes
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  // The following line of code actually outputs "undefined".
  // It seems each process has its own copy of my_shared_var.
  console.log(my_shared_var);

  // Then perform query against my_shared_var.
  // The query should be performed by worker processes,
  // otherwise the master process will become bottleneck
  var result = query(my_shared_var);
}

各プロセスがデータに簡単にアクセスできるように、大きなテーブルを MongoDB に保存しようとしました。しかし、テーブルのサイズが非常に大きいため、MongoDB がインデックスを使用してもクエリを完了するのに約 10 秒かかります。これは遅すぎて、私のリアルタイム アプリケーションには受け入れられません。データをメモリに保持する Redis も試しました。しかし、Redis はキーと値のストアであり、私のデータはテーブルです。データをメモリにロードする C++ プログラムも作成しましたが、クエリに 1 秒もかからなかったので、これを node.js でエミュレートしたいと考えています。

4

7 に答える 7

16

あなたの質問を一言で表現すると、MASTER エンティティのデータを WORKER エンティティと共有する必要があります。イベントを使用して非常に簡単に実行できます。

マスターからワーカーへ:

worker.send({json data});    // In Master part

process.on('message', yourCallbackFunc(jsonData));    // In Worker part

ワーカーからマスターへ:

process.send({json data});   // In Worker part

worker.on('message', yourCallbackFunc(jsonData));    // In Master part

この方法でデータを双方向に送受信できることを願っています。他のユーザーも回答を見つけられるように、役立つと思われる場合は、回答としてマークしてください。ありがとう

于 2016-04-04T08:15:54.313 に答える
9

node.js がサポートしていない共有メモリを探しています。データベースへのクエリmemcachedの使用など、代替手段を探す必要があります。

于 2012-06-09T23:54:07.383 に答える
6

アプリケーションで読み取り専用アクセスが問題ない場合は、独自の共有メモリ モジュールを試してください。内部で使用mmapされるため、データは一度にすべてではなく、アクセスされるたびにロードされます。メモリは、マシン上のすべてのプロセス間で共有されます。使い方はとても簡単です:

const Shared = require('mmap-object')

const shared_object = new Shared.Open('table_file')

console.log(shared_object.property)

文字列または数値のキー値ストアへの通常のオブジェクト インターフェイスを提供します。私のアプリケーションでは超高速です。

テスト用に利用可能なモジュールの実験的な読み書きバージョンもあります。

于 2016-03-10T06:40:54.767 に答える
6

node.js では、フォークは C++ とは異なります。プロセスの現在の状態をコピーするのではなく、新しいプロセスを実行します。したがって、この場合、変数は共有されません。コードのすべての行はすべてのプロセスで機能しますが、マスター プロセスでは cluster.isMaster フラグが true に設定されています。ワーカー プロセスごとにデータをロードする必要があります。すべてのプロセスには独自のコピーがあるため、データが非常に大きい場合は注意してください。必要になったらすぐにデータの一部をクエリするか、メモリ内ですべてが本当に必要な場合は待つ必要があると思います。

于 2012-06-09T23:54:25.560 に答える
2

Redis を使用できます。

Redis は、オープン ソースであり、BSD ライセンスを取得している高度なキー値キャッシュおよびストアです。キーには文字列、ハッシュ、リスト、セット、ソート済みセット、ビットマップ、およびハイパーログログを含めることができるため、データ構造サーバーと呼ばれることがよくあります。

redis.io

于 2015-03-25T09:02:33.403 に答える
0

この質問は、ちょうど 10 年前の 2012 年に投稿されました。他の回答で言及されていないため、Node.js は共有メモリをサポートするワーカー スレッドをサポートするようになりました。

ドキュメントから直接:

ワーカー (スレッド) は、CPU を集中的に使用する JavaScript 操作を実行する場合に役立ちます。child_process や cluster とは異なり、worker_threads はメモリを共有できます。これは、ArrayBuffer インスタンスを転送するか、SharedArrayBuffer インスタンスを共有することによって行われます。

于 2022-02-01T16:38:36.897 に答える