web-dev-qa-db-ja.com

node.jsで、マスタープロセスによって初期化され、ワー​​カープロセスによってアクセスできる共有変数を宣言するにはどうすればよいですか?

以下が欲しい

  • 起動時に、マスタープロセスはファイルから大きなテーブルをロードし、それを共有変数に保存します。このテーブルには、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でこれをエミュレートしたいと思います。

23
Jacky Lee

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

6
Martin Blech

あなたの質問を一言で言えば、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

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

13
Shivam

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

const Shared = require('mmap-object')

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

console.log(shared_object.property)

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

モジュールの実験的な読み取り/書き込みバージョン テストに使用できるものもあります。

5
Allen Luce

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

4
Vadim Baryshev

Redisを使用できます。

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

redis.io

3
Reza Roshan