在node.js中,如何声明一个可由主进程初始化并由工作进程访问的共享variables?

我想要以下

  • 在启动过程中,主进程从文件加载一个大表并将其保存到共享variables中。 该表有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中,以便每个进程可以轻松访问数据。 但是表大小非常巨大,即使使用索引,也需要大约10秒才能完成我的查询。 这太慢了,不适合我的实时应用程序。 我也试过Redis,它在内存中保存数据。 但是Redis是一个重要的商店,我的数据是一张桌子。 我也写了一个C ++程序来加载数据到内存中,查询花了不到1秒,所以我想在node.js中模拟这个。

您正在寻找共享内存,哪个node.js只是不支持 。 你应该寻找替代品,例如查询数据库或使用memcached 。

如果我用几句话翻译你的问题,你需要和WORKER实体共享MASTER实体的数据。 使用事件可以非常容易地完成:

从主人到工人:

 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 

我希望这样可以双向发送和接收数据。 如果您觉得有用,请将其标记为答案,以便其他用户也可以find答案。 谢谢

在node.js中,fork不像C ++中的那样工作。 这不是复制进程的当前状态,而是运行新进程。 所以,在这种情况下,variables不被共享。 每行代码都适用于每个进程,但主进程将cluster.isMaster标志设置为true。 您需要为每个工作进程加载数据。 如果您的数据真的很大,请小心,因为每个进程都有自己的副本。 我想你需要在需要的时候尽快查询部分数据,或者如果你真的需要在内存中使用这些数据的话。

如果您的应用程序只读访问权限不错,请尝试使用我自己的共享内存模块 。 它在封面下使用了mmap ,所以数据在被访问时被加载,而不是一次全部加载。 内存在机器上的所有进程之间共享。 使用它是非常容易的:

 const Shared = require('mmap-object') const shared_object = new Shared.Open('table_file') console.log(shared_object.property) 

它为您提供了一个string或数字键值存储的常规对象接口。 在我的应用程序中速度非常快。

还有一个可用于testing的模块的实验读写版本 。

你可以使用Redis。

Redis是一个开源的BSD许可的高级键值caching和存储。 它通常被称为数据结构服务器,因为密钥可以包含string,哈希,列表,集合,有序集合,位图和超级日志logging。

redis.io