在node.js进程之间读取共享巨大的哈希值

时间:2014-03-15 12:40:56

标签: javascript node.js concurrency process sharding

情况

我有〜10.000.000个时间键和相关的JSON数据点。 我需要在所有这些数据点上执行一个JavaScript函数fn(time,data [time],params)多次(~10,000)并使用不同的参数。

目前的方法

我使用npm模块hashtable将数据存储在V8s VM之外。

//PSEUDO-STRUCTURE

var params = [{...},{...},...];
var HashTable = require("hashtable");
var myBigObject = new HashTable();

var timeIndices = {};
for(...) {
   myBigObject.put(time,data);        //<-- many times
   timeIndices[time] = true;
}
indices = Object.keys(indices);
params.forEach(function(currentParams) {
   timeIndices.forEach(function(time) {
       var data = myBigObject.get(time);
       fn(time,data,currentParams);
   });
});

问题

我遇到了以下问题:

  • V8无法存储所有JSON数据, - &gt;使用哈希表修复
  • V8无法处理所有数据,因为内存不足,&gt;使用--max_old_space_size(64位)
  • 修复

这在内存方面有效,但速度很慢。我怎样才能加快速度呢?

  1. 对工人进行分区参数(有效,但受可用内存限制)

    • 工作人员如何共享相同的工作量,而不是他们每个人都持有副本?
      • 内存数据库(Redis,memcached)具有内存效率,但由于这些数量的密钥或序列化/反序列化较大的JSON-blob而速度很慢
      • node-mmap(将JSON存储为缓冲区,通过mmap共享缓冲区,解析JSON仍然需要花费太多时间)
  2. 工作人员的分区时间

    • 不可行,因为工作人员的目的是完成整个时间表
  3. 只保留部分对象在内存中并在需要时从磁盘重新加载(速度慢,但内存效率高)

  4. TLDR

    如何在node.js进程之间共享一个巨大的只读JavaScript哈希对象,而不会增加内存占用量?

    更新,创意2.0

    1. 编写一个C ++程序,将数据加载到内存中,启动嵌入式V8环境的C ++ worker。这会让我在同一个内存上运行多个V8虚拟机吗?

2 个答案:

答案 0 :(得分:0)

(注意:评论中的空间太小,所以这里有一个建议)

以下是几个问题?

  1. 有多少&#39; params&#39;你有没有元素?
  2. 为什么redis不适合你呢?这应该完全是它的一种东西,持有10密耳的键/值和大量的恒定时间读数。
  3. fn是否需要按顺序运行?一次执行需要多长时间?它是做数据突变还是仅仅计算,是否需要将对象拉回来?或者什么?
  4. 这是一个想法:

    • 予。用redis保存数据。
    • II。一个全局indices密钥。
    • III。并行运行x的工作者(x可由您的处理器数量,(fn)的结构等配置)。根据设置的不同,您甚至可以将其拆分为单独的节点进程(甚至在不同的计算机上?)但是它们都会使用相同的redis进行通信。
    • IV。每个工作者fn获取他的时间索引并获得全局共享的redis句柄。
    • 诉每个工人都会写下他的本地人。数据到新的redis数据库?

    这些步骤中哪一个对您有用?

答案 1 :(得分:0)

我有类似的需求,同样没有找到我想要的包。所以我从&#34;更新,创意2.0&#34;中得到了启示。段落和implemented a module.

它在共享内存中维护一个哈希结构的副本(从文件映射),并允许同一个盒子上的多个Node进程进行只读查询。

它是用C ++编写的,使用Boost's unordered_map作为哈希系统。