Node.js集群模式下如何共享内存数据?
我用 Node.js 的 cluster 模块启动了多个工作进程,想在主进程和各个子进程之间共享一些配置数据。但发现每个进程都有自己独立的内存空间,修改一个进程里的变量,其他进程根本看不到。
试过在主进程里定义一个全局对象 global.config = { port: 3000 },然后 fork 子进程去读,结果子进程拿到的是初始值,主进程后续更新它也同步不过去。有没有办法让这些进程共享同一块内存?或者有什么推荐的通信方式?
目前想到的是用 Redis 或者文件,但感觉太重了。看到文档说可以用 process.send() 和 cluster.workers[id].send() 通信,但频繁发送大量数据会不会影响性能?
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
global.config = { port: 3000 };
for (let i = 0; i < numCPUs; i++) {
const worker = cluster.fork();
// 这里想更新 config,但子进程收不到
setTimeout(() => {
global.config.port = 4000;
}, 1000);
}
} else {
console.log('Worker sees:', global.config.port); // 始终是 3000
}
要解决共享配置数据的问题,可以考虑以下几种方案:
1. 使用进程间通信(IPC):你提到的 process.send() 和 cluster.workers[id].send() 就是这个思路。虽然会有一定的性能开销,但对于小量数据的同步还是可行的。比如在主进程中更新配置后,通过发送消息通知子进程更新自己的配置。
2. 使用内存数据库:Redis 或 Memcached 都是可以考虑的轻量级方案。它们提供了快速的内存访问速度,并且支持发布订阅机制,适合进程间的数据同步。
3. 使用文件系统:虽然你说这种方式太重了,但如果数据量不大,写入速度不是瓶颈,也可以考虑将配置信息存储在文件中,各进程定时检查文件的变化并更新配置。
4. 共享内存:Node.js 内置的 cluster 模块并不直接支持共享内存,但可以通过一些第三方库来实现。例如 node-shared 或 shared-buffer 这些模块可以提供类似的功能。
针对你的情况,如果不想引入额外的服务或库,使用进程间通信是最直接的解决方案。下面是一个简单的示例,展示了如何在主进程中更新配置并通过 IPC 通知子进程:
这个例子展示了主进程如何初始化配置并将其发送给子进程,以及如何在更新配置后再次发送更新后的配置给所有子进程。子进程则监听消息事件来接收配置并更新自身的配置副本。注意这种方式下的数据同步是单向的(从主到子),如果需要双向通信,还需要进一步扩展代码逻辑。