如何保留共享节点集群中所有节点进程的变量?
Posted
技术标签:
【中文标题】如何保留共享节点集群中所有节点进程的变量?【英文标题】:how to keep variables that share all node processes in node cluster? 【发布时间】:2013-01-27 09:26:28 【问题描述】:似乎所有节点woker进程都在工作,就好像它正在执行同一应用程序的新副本一样。但是希望保留一些由节点集群中的所有节点工作人员(子进程)共享的变量。有没有一种简单的方法可以做到这一点?
【问题讨论】:
你看过redis这样的数据库吗?即使有办法,如果没有适当的锁定机制,这听起来也是个坏主意。 @Aaron Dufour 感谢您的回复。是的。 redis 是一种选择。我也想过。但是我不能不使用数据库吗? 我认为不存在这样的方法。你当然可以想出一些东西,例如使用process.send
和worker.send
(参见cluster
文档),但这既不安全也不快速。像 Redis 这样的临时数据存储绝对是您的最佳选择。
【参考方案1】:
所有工作进程确实是您的应用程序的新副本。每个 worker 都是使用 child_process.spawn 创建的全功能进程。 所以不,他们不共享变量。这种方式可能是最好的。 如果您想在工作进程(通常是会话)之间共享信息,您应该考虑将这些信息存储在数据库中。
如果您已准备好一直使用节点,则可以使用 dnode 之类的东西让您的工作人员向主进程请求数据。
【讨论】:
dnode链接转到File not found
页面
我需要传递媒体管道(实例化的对象),而 Redis 或键值存储无法做到这一点:|【参考方案2】:
您可以尝试在主进程和子进程之间进行通信。例如:
脚本 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!');
【讨论】:
【参考方案3】:我为此使用了外部 memcached 或 redis 服务器。
【讨论】:
你能分享一个例子吗?我正在尝试从 memcache 中的子节点获取数据集以从主节点获取,但无法正常工作 这更适合作为评论而不是作为答案【参考方案4】:我认为集群的整个想法是拥有可以在不同 CPU 上独立运行的实例。共享它们都可以访问和更改的内存(全局变量)会引入更多复杂性(锁等)并使这些实例相互依赖。
外部数据库将是一个很好的解决方案,因为它可以处理所有数据访问问题,但它很可能会降低性能。
消息传递是一个更好的主意。您可以在集群中保存 var 的本地实例。当集群更新值时,向其余集群发送消息并更新值。这很棒,因为它是异步且非阻塞的,但您的值更新不会立即反映。
这个怎么样:将变量存储在数据库上,每次有值更改时通知实例。他们可以将新值存储在本地变量中,并仅在需要时进行数据库调用
【讨论】:
【参考方案5】:如果您希望以只读方式共享内容,请查看mmap-object。我将它用于大型内存查找表。
刚刚在服务器上检查,一个 346M 的文件总共占用了 156M 的内存(mmap 仅在访问的页面中)并且 mmap-object 在 44 个进程之间共享它,每个进程的开销为 3.5M。
因为它是只读的,所以我不必担心进程间锁定和可能带来的混乱。
【讨论】:
【参考方案6】:目前还没有人提到这一点,但这是 Node Worker Threads 的完美案例,它刚刚在最新版本的 Node v11.11.0 中退出实验模式。
【讨论】:
以上是关于如何保留共享节点集群中所有节点进程的变量?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用快照进行elasticsearch迁移,使用共享文件夹方式