2013-02-12 101 views
16

似乎所有的节点工作进程都在工作,就好像它正在执行相同应用程序的新副本一样。但是想保留节点集群中所有节点工作人员(子进程)共享的变量。有没有简单的方法来做到这一点?如何保留共享节点集群中所有节点进程的变量?

+2

你看过像redis这样的数据库吗?即使有办法,没有适当的锁定机制,这听起来像一个坏主意。 – 2013-02-12 06:08:00

+0

@Aaron Dufour感谢您的回复。是。 redis是一种选择。我也想过了。但是我不能使用数据库来做到这一点吗? – 2013-02-12 06:23:29

+1

我不认为这样的方法存在。您当然可以想出一些东西,例如使用'process.send'和'worker.send'(请参阅'cluster'文档),但它既不安全也不快。像Redis这样的临时数据存储绝对是您的最佳选择。 – 2013-02-12 14:30:37

回答

14

所有工作进程确实是应用程序的新副本。每个工作者都是使用child_process.spawn创建的全功能流程。 所以不,他们不共享变量。这可能是最好的方式。 如果您想在工作进程(通常会话)之间共享信息,您应该查看将这些信息存储在数据库中。

如果您准备好一直走节点,您可以使用类似dnode这样的东西让您的工作人员向主进程询问数据。

+0

dnode链接转到'File not found'页面 – zavg 2015-05-30 22:26:53

+1

谢谢,我现在指向github回购。 – Floby 2015-06-01 10:06:37

+0

我需要将媒体管道(实例化对象)传递给我,这是我无法用redis或关键值存储进行的操作: – Antoine 2017-12-24 02:21:23

12

您可以尝试在主进程和子进程之间进行通信。例如:

脚本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!'); 
2

我觉得集群的整体思路是具有可独立运行的实例不同的cpus。共享内存(一个全局变量),它们都可以访问和更改引入更多的复杂性(锁等),并使这些实例相互依赖。

外部数据库将是一个很好的解决方案,因为它处理所有数据访问问题,但它很可能会降低性能。

消息传递是一个更好的主意。您可以在集群中保存var的本地实例。当群集更新该值时,向其余部分发送消息并更新该值。这非常棒,因为它是异步和非阻塞的,但您的价值更新不会立即反映出来。

这个怎么样:在数据库上存储变量,每次值变化都会通知实例。他们可以将新值存储在本地变量中,并仅在需要时才拨打db调用

4

我为它使用了外部memcached或redis服务器。

+1

你能分享一个例子吗?我打算从memcache中的子项获取数据集以从master获取数据集,但不工作 – mithra 2016-01-20 10:26:58

+0

这适合作为评论而不是作为答案 – renatoargh 2017-05-08 19:03:35

0

如果您想要以只读方式分享内容,请查看mmap-object。我将它用于大内存查找表。

刚刚在一台服务器上检查,一个346M文件总共占用了156M的内存(mmap只能访问内存中的页面)和mmap对象在44个进程中共享,每个进程的开销为3.5M。

因为它是只读的,所以我不必担心进程间锁定和可能带来的混乱。