как сохранить переменные, которые совместно используют все процессы узлов в кластере узлов?

Кажется, что все рабочие процессы узла работают так, как будто он выполняет новую копию того же приложения. Но хотелось бы сохранить некоторые переменные, которые являются общими для всех рабочих узлов (дочерних процессов) в кластере узлов. Есть ли простой способ сделать это?


person lahiru madhumal    schedule 12.02.2013    source источник
comment
Вы заглядывали в базу данных, например Redis? Даже если есть способ, без надлежащих механизмов блокировки это звучит как плохая идея.   -  person Aaron Dufour    schedule 12.02.2013
comment
@Aaron Dufour спасибо за ответ. да. Redis - это один из вариантов. Я тоже думал об этом. Но разве я не могу сделать это без использования базы данных?   -  person lahiru madhumal    schedule 12.02.2013
comment
Я не думаю, что такой метод существует. Вы, конечно, могли бы что-то придумать, например, используя process.send и worker.send (см. cluster документы), но это было бы ни безопасно, ни быстро. Хранилище временных данных, такое как Redis, определенно ваш лучший вариант.   -  person Aaron Dufour    schedule 12.02.2013


Ответы (6)


Все рабочие процессы действительно являются новыми копиями вашего приложения. Каждый рабочий процесс — это полнофункциональный процесс, созданный с помощью child_process.spawn. Так что нет, они не используют общие переменные. И, наверное, лучше всего так. Если вы хотите обмениваться информацией между рабочими процессами (обычно сеансами), вам следует рассмотреть возможность хранения этой информации в базе данных.

Если вы готовы пройти весь путь узла, вы можете использовать что-то вроде dnode, чтобы ваши рабочие запросы запрашивали данные у главного процесса. .

person Floby    schedule 12.02.2013
comment
Ссылка dnode ведет на File not found страницу - person zavg; 31.05.2015
comment
Мне нужно, чтобы медиаконвейеры (экземпляры объектов) передавались, чего я не могу сделать с помощью Redis или хранилища значений ключа: | - person Anthony; 24.12.2017

Вы можете попытаться установить связь между основным процессом и дочерними процессами. Например:

скрипт 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!');
person hWndepT    schedule 12.02.2013

Я использовал для этого внешний сервер memcached или redis.

person vodolaz095    schedule 13.12.2013
comment
Не могли бы вы поделиться примером? я пытаюсь получить набор данных от дочернего элемента в memcache, чтобы получить от мастера, но не работает - person mithra; 20.01.2016
comment
Это больше подходит как комментарий, чем как ответ - person Renato Gama; 08.05.2017

Я думаю, что вся идея кластера состоит в том, чтобы иметь экземпляры, которые могут работать независимо на разных процессорах. Совместное использование памяти (глобальной переменной), к которой они оба могут обращаться и изменять, вносит дополнительную сложность (блокировки и т. д.) и делает эти экземпляры зависимыми друг от друга.

Внешняя база данных была бы хорошим решением для этого, поскольку она заботится обо всех проблемах с доступом к данным, но, скорее всего, снижает производительность.

Обмен сообщениями — лучшая идея. Вы можете хранить локальные экземпляры var в своих кластерах. Когда кластер обновляет значение, отправьте сообщение остальным и обновите значение. Это здорово, потому что это асинхронно и не блокирует, но опять же ваше обновление значения не будет отображаться немедленно.

Как насчет этого: хранить переменные в базе данных и каждый раз при изменении значения уведомлять экземпляры. Они могут хранить новые значения в локальных переменных и выполнять вызовы базы данных только тогда, когда это необходимо.

person srosh    schedule 13.02.2013

Если вы хотите поделиться информацией только для чтения, проверьте mmap-object. Я использую его для больших таблиц поиска в памяти.

Только что проверив на сервере, файл размером 346 МБ занимает в общей сложности 156 МБ памяти (mmap-только страницы в том, к чему обращаются), и mmap-объект разделяет его между 44 процессами, что составляет 3,5 МБ на каждый процесс.

Поскольку он доступен только для чтения, мне не нужно беспокоиться о межпроцессной блокировке и беспорядке, который может возникнуть.

person Allen Luce    schedule 27.09.2016

Никто еще не упомянул об этом, но это идеальный случай для потоков рабочих узлов, которые только что вышли из экспериментальный режим в последней версии Node v11.11.0.

person Mauvis Ledford    schedule 07.03.2019