すべてのノードウォーカープロセスが、同じアプリケーションの新しいコピーを実行しているかのように機能しているようです。ただし、ノードクラスター内のすべてのノードワーカー(子プロセス)によって共有されるいくつかの変数を保持したいと思います。これを行う簡単な方法はありますか?
すべてのワーカープロセスは、実際にアプリケーションの新しいコピーです。各ワーカーは、child_process.spawnで作成されたフル機能のプロセスです。いいえ、変数を共有しません。そして、それはおそらくこの方法が最善です。ワーカープロセス(通常はセッション)間で情報を共有する場合は、これらの情報をデータベースに保存することを検討する必要があります。
完全にノードに移動する準備ができている場合は、 dnode のようなものを使用して、ワーカーにマスタープロセスにデータを要求させることができます。
マスタープロセスと子プロセスの間の通信を試みることができます。例えば:
スクリプトtest.master.js:
var cluster = require('cluster');
var childScript = __dirname + '/test.child.js';
cluster.setupMaster({ exec: childScript });
proc = cluster.fork();
proc.on('message', function(message) {
console.log('message from child: ', message);
proc.send('Hello from master!');
});
スクリプトtest.child.js:
console.log('Child initializing..');
process.on('message', function(message) {
console.log('message from master: ', message);
});
process.send('Hello from Child!');
外部のmemcachedまたはredisサーバーを使用しました。
クラスターの全体的な考え方は、異なるCPUで独立して実行できるインスタンスを持つことだと思います。アクセスと変更の両方が可能なメモリ(グローバル変数)を共有すると、複雑さが増し(ロックなど)、これらのインスタンスが相互に依存するようになります。
外部データベースは、すべてのデータアクセスの問題を処理するため、これに対する優れたソリューションですが、パフォーマンスが低下する可能性があります。
メッセージングはより良い考えです。変数のローカルインスタンスをクラスターに保持できます。クラスターが値を更新したら、残りのクラスターにメッセージを送信して値を更新します。これは非同期で非ブロッキングであるため素晴らしいですが、値の更新はすぐには反映されません。
これはどうですか:変数をデータベースに保存し、値が変更されるたびにインスタンスに通知します。新しい値をローカル変数に格納し、必要な場合にのみdb呼び出しを行うことができます
読み取り専用で共有したい場合は、 mmap-object を確認してください。大規模なメモリ内ルックアップテーブルに使用します。
サーバー上でちょうど今チェックすると、346Mファイルは合計156Mのメモリ(アクセスされたもののページのみをmmap)を占有し、mmapオブジェクトはそれを44プロセス間で共有し、プロセスごとのオーバーヘッドは350万になります。
読み取り専用なので、プロセス間のロックや混乱を心配する必要はありません。
まだ誰もこれについて言及していませんが、これは Node Worker Threads の完璧なケースであり、最新バージョンのNode v11.11.0で実験モードから抜け出しました。