В node.js, как объявить общую переменную, которая может быть инициализирована мастер-процессом и доступна для рабочих процессов? - программирование
Подтвердить что ты не робот

В node.js, как объявить общую переменную, которая может быть инициализирована мастер-процессом и доступна для рабочих процессов?

Я хочу следующее

  • Во время запуска главный процесс загружает большую таблицу из файла и сохраняет ее в общую переменную. Таблица имеет 9 столбцов и 12 миллионов строк, размер 432 МБ.
  • Рабочие процессы запускают 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 - это хранилище ключей, а мои данные - таблица. Я также написал программу на С++ для загрузки данных в память, и запрос занял менее 1 секунды, поэтому я хочу эмулировать это в node.js.

4b9b3361

Ответ 2

Если я переведу свой вопрос в нескольких словах, вам нужно поделиться данными объекта 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

Я надеюсь, что так вы сможете отправлять и получать данные в двунаправленном режиме. Пожалуйста, отметьте его как ответ, если вы сочтете это полезным, чтобы другие пользователи могли также найти ответ. Благодаря

Ответ 3

В node.js fork работает не так, как в С++. Он не копирует текущее состояние процесса, он запускает новый процесс. Итак, в этом случае переменные не разделяются. Каждая строка кода работает для каждого процесса, но мастер-процесс имеет флаг cluster.isMaster, установленный в true. Вам необходимо загрузить данные для каждого рабочего процесса. Будьте осторожны, если ваши данные действительно огромны, потому что каждый процесс будет иметь свою собственную копию. Я думаю, вам нужно запросить части данных, как только они вам понадобятся, или ждать, если вам действительно нужно все это в памяти.

Ответ 4

Если доступ для чтения подходит для вашего приложения, попробуйте мой собственный модуль общей памяти. Он использует mmap под обложками, поэтому данные загружаются по мере их доступа и не все одновременно. Память распределена между всеми процессами на машине. Использование его очень просто:

const Shared = require('mmap-object')

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

console.log(shared_object.property)

Он предоставляет вам обычный интерфейс объекта для хранения значений строк или чисел. Это очень быстро в моих приложениях.

Существует также экспериментальная версия для чтения и записи модуля, доступная для тестирования.

Ответ 5

Вы можете использовать Redis.

Redis - это открытый исходный код, лицензированный BSD, расширенный кеш-ключ и хранилище. Он часто упоминается как сервер структуры данных, поскольку ключи могут содержать строки, хэши, списки, наборы, отсортированные наборы, растровые изображения и гиперлогологи.

redis.io