21

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

大多数查询可以在十分之一秒内得到答复。节点万岁!

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

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

但是,因为这个数据结构太大了,我想在worker或者线程或者你有什么之间共享它,所以我不烧几百兆。这将是非常安全的,因为不会写入数据结构。任何其他语言的典型“fork()”都可以做到。

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

但是有办法吗?

背景:

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

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

Node 的集群使用了一个名为“fork”的调用,但它实际上并不是现有进程的一个 fork,它正在产生一个新进程。所以再一次,没有共享内存。

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

4

4 回答 4

5

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

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

于 2013-04-16T07:01:27.897 回答
0

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

有了这个...

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

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

于 2015-02-03T20:45:09.033 回答
0

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

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

于 2013-02-14T06:46:35.393 回答
0

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

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

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

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

于 2013-02-14T08:11:46.257 回答