【问题标题】:Riak MapReduce - map works, reduce receives very small subset of resultsRiak MapReduce - map 工作,reduce 收到非常小的结果子集
【发布时间】:2014-05-15 15:50:33
【问题描述】:

我在 Ubuntu 12.10(最新)上使用 Riak 2.0.0b1。这是一个开发者盒子,所以我只有一个 Riak 实例 - 没有集群等。

我已将大约 100k JSON 文档(每个大约 300 字节)放入一个存储桶中,现在正尝试对其进行 mapreduce。数据是随机的,我在其中一个键上也有 2i 索引,它基本上将数据集分成 10 个几乎均匀的部分,大约 10k 个文档。

此查询按预期工作:

curl -XPOST -d'{
  "inputs": {"bucket": "bucket", "index": "idx_bin", "key": "10"},
  "query": [
    {
      "map": {
        "language": "javascript",
        "source": "Riak.mapValuesJson"
      }
    }
  ]
}' http://localhost:8080/mapred -H 'Content-Type: application/json' | python -m json.tool | egrep '^ {4}\{' | wc -l

9974

得到了大约 10k 个结果。现在,如果我想在 reduce 步骤中做某事,我会得到一个没有意义的答案:

curl -XPOST -d'{
  "inputs": {"bucket": "bucket", "index": "idx_bin", "key": "10"},
  "query": [
    {
      "map": {
        "language": "javascript",
        "source": "Riak.mapValuesJson"
      }
    },
    {
      "reduce": {
         "language": "javascript",
        "source": "function(o) { return [o.length] }"
      }
    }
  ]
}' http://localhost:8080/mapred -H 'Content-Type: application/json' | python -m json.tool

[
    15
]

如果我达到了一些(未记录的)限制或对象的完整列表,而不是 15,我希望在这里看到一个错误。(这个数字在运行之间会有所不同;有时还有更多。)我去了到配置并完成此操作:

javascript.map_pool_size = 64
javascript.reduce_pool_size = 64
javascript.maximum_stack_size = 32MB
javascript.maximum_heap_size = 64MB

根本没有帮助。

发生了什么以及如何在reduce阶段获取所有对象?

【问题讨论】:

    标签: mapreduce riak


    【解决方案1】:

    reduce 函数被多次调用。 map 函数将在集群中大约 1/3 的 vnode 上运行(在 ring_size 64 的集群中是 22 次),每次从 map 函数中获得结果时都会调用 reduce 函数,它的第一个参数是一个列表,其中包含上一次运行 reduce 函数的结果和 map 函数的结果。在您的情况下,您计算了从第一个 vnode 返回的值,然后将其作为包含在第二个 vnode 的结果中的值传递,并且仅计为单个值。

    您需要做的是让 reduce 函数返回一个易于与其他值区分开来的值/对象,例如

    function(o) {
      var prevCount = 0;
      var countObjects = 0;
      for each (e in o) {
        if (typeof e === 'object' && typeof e.reduce_running_total === 'number') {
           prevCount += e.reduce_running_total;
           countObjects += 1;
        }
      }
      return([{"reduce_running_total":o.length + prevCount - countObjects}]);
    }
    

    或者,您可以节省一些网络带宽,而不是让 map 阶段返回所有对象,而是让 map 函数为找到的每个键返回一个文字 [1],然后 reduce 函数简单地总结所有数字在输入列表中并返回它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多