有没有办法在Node.JS中的worker / threads / something之间共享内存?

时间:2013-02-14 06:27:16

标签: multithreading node.js parallel-processing fork

我有一个Node应用程序,可访问静态,大型(> 100M),复杂的内存数据结构,接受查询,然后通过HTTP向客户端提供一小部分数据。

大多数查询都可以在十分之一秒内得到解答。 Hurray for Node!

但是,对于某些查询,搜索此数据结构需要几秒钟。这很糟糕,因为其他人都必须等待。

为了有效地为更多客户服务,我想使用某种并行性。

但是,因为这个数据结构太大了,我想在工作者或线程中分享它或者你有什么,所以我不会烧掉数百兆字节。这将是非常安全的,因为数据结构不会被写入。任何其他语言的典型'fork()'都可以。

然而,据我所知,在Node中进行并行化的所有标准方法都明确地使这变得不可能。为安全起见,他们不希望您分享任何内容。

但有办法吗?

背景:

将此数据结构放在数据库中,或使用memcached或类似的东西是不切实际的。

WebWorker API库和类似的只允许将短序列化消息传入和传出工作者。

Node的Cluster使用名为'fork'的调用,但它实际上不是现有进程的分支,而是生成一个新进程。所以再一次,没有共享内存。

可能真正正确的答案是使用类似文件系统的共享内存,即tmpfs或mmap。有一些节点库使mount()和mmap()可用于这样的事情。不幸的是,必须在同步搜索和读取之上实现复杂的数据结构访问。我的应用程序使用dicts数组的数组,依此类推。不必重新实现所有这些就好了。

4 个答案:

答案 0 :(得分:5)

我尝试从nodejs编写共享内存访问的C / C ++绑定。 https://github.com/supipd/node-shm

仍在进行中(但为我工作),如果有错误或建议可能有用,请通知我。

答案 1 :(得分:0)

使用waf构建是旧样式(节点0.6及以下),新构建是使用gyp。

您应该查看节点集群(http://nodejs.org/api/cluster.html)。不清楚这会在没有更多细节的情况下帮助您,但是这会使用fork在同一台机器上运行多个节点进程。

答案 2 :(得分:0)

实际上Node确实支持产生过程。我不确定Node的fork与真正的fork有多接近,但你可以尝试一下:

http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options

顺便说一句:Node不适合这种情况。它与任何其他语言/ Web服务器一样合适。您始终可以在不同的端口上触发服务器的多个实例,并将代理放在前面。

如果您需要更多内存 - 请添加更多内存。 :) 它是如此简单。此外,您应该考虑将所有数据放在专用的内存数据库中,如Redis或Memcached(如果需要复杂查询,甚至可以使用Couchbase)。您不必再担心重复这些数据了。

答案 3 :(得分:0)

大多数Web应用程序大部分时间都在等待网络缓冲区和数据库读取。 Node.js旨在擅长这个io绑定工作。如果您的工作真正受到CPU的约束,那么另一个平台可能会为您提供更好的服务。

有了这个......

  1. 使用process.nextTick(甚至可能是嵌套块)来确保昂贵的CPU工作是正确异步的,并且不允许阻塞您的线程。这将确保一位客户提出昂贵的请求不会对所有其他客户产生负面影响。

  2. 使用node.js群集为系统中的每个CPU添加工作进程。工作进程都可以绑定到单个HTTP端口,并使用Memcached或Redis来共享内存状态。工作人员还有一个消息传递API,可用于保持进程内存缓存同步,但它有一些一致性限制。