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

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

大多数查询可以在十分之一秒内回答。 华丽的节点!

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

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

但是,由于这个数据结构如此之大,我想在工作者或者线程之间分享,或者你有什么,所以我不会烧数百兆字节。 这将是完全安全的,因为数据结构不会被写入。 任何其他语言的典型“fork()”都可以。

但是,据我所知,在Node中执行并行的所有标准方法明确地使这是不可能的。 为了安全,他们不希望你分享任何东西。

但有没有办法?

背景:

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

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

节点的群集使用名为“叉”的调用,但它不是真正的现有过程的叉,它正在产生一个新的。 所以再一次,没有共享的记忆。

可能真正正确的答案是使用文件系统访问共享内存,也就是tmpfs或mmap。 有一些节点库使得mount()和mmap()完全可以用于这样的事情。 不幸的是,人们必须在同步查询和读取之上实现复杂的数据结构访问。 我的应用程序使用数组的字典等数组。 不用重新实现就好了。

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

仍在工作(但为我工作),也许有用,如果错误或build议,告诉我。

老式build筑(节点0.6及以下),新build与gyp。

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

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

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

顺便说一下,Node不适用于此。 它与任何其他语言/networking服务器一样合适。 您可以随时在不同的端口上激发您的服务器的多个实例,并将代理放在前面。

如果你需要更多的内存 – 增加更多的内存。 :) 它是如此简单。 另外,您应该考虑将所有这些数据放在像Redis或Memcached这样的专用内存数据库(如果需要复杂的查询,甚至是Couchbase)。 您不必担心重复该数据。

大多数Web应用程序大部分时间都在等待networking缓冲区和数据库读取。 Node.js被devise成在这个io绑定的工作中performance突出。 如果你的工作真的受到CPU的约束,你可能会被另一个平台更好地服务。

随着那个…

  1. 使用process.nextTick(也许甚至嵌套块),以确保昂贵的CPU工作是正确的asynchronous,不允许阻止你的线程。 这将确保一个客户做出昂贵的请求不会对所有其他客户造成负面影响。

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