我有一个大约有900,000条记录的存储桶。这些记录中的大多数在二级索引中具有PERSISTED状态。我想检索所有base_urls以及所有标记为PERSISTED的文档的每个base_url的文档数量。
以下是查询:
curl -X POST -H "content-type: application/json" \
http://localhost:8098/mapred?chunked=true --data @-<<\EOF
{
"timeout":600000,
"inputs":{
"bucket":"test-bucket",
"index":"status_bin",
"key":"PERSISTED"
},
"query":[{
"map":{
"language":"javascript",
"source":"
function(value, keyData, arg) {
var data = Riak.mapValuesJson(value)[0];
var obj = {};
obj[data.base_url] = 1;
return [obj];
}
"
}
},
{
"reduce":{
"language":"javascript",
"source":"
function(values, arg){
return [values.reduce(
function(acc, item){
for(var base_url in item){
if(acc[base_url]) {
acc[base_url] = acc[base_url] + 1
} else {
acc[base_url] = item[base_url];
}
}
return acc;
})
];
}
"
}
}]
EOF
这是在10分钟后超时。
我使用的是具有20Gb内存的16核3Ghz AWS节点。
我的配置或上述查询是否存在我可能做错的事情?
可能需要这么长时间吗?
为了提供透视,MySQL中的等效查询看起来像这样
SELECT COUNT(*),catalog FROM url GROUP BY catalog;
我还没有尝试过,但我怀疑在MySQL中,上述查询超过900,000条记录的结果集需要几秒钟。我并不意味着将Riak与MySQL进行比较,因为我意识到它们非常不同,但我想知道我至少可以在10分钟内执行上述查询。
谢谢!
答案 0 :(得分:1)
Riak中的JavaScript MapReduce作业使用SpiderMonkey JavaScript VM池,根据您的使用模式调整此池的大小非常重要,以避免或至少减少争用。通过app.config文件中的'map_js_vm_count'和'reduce_js_vm_count'参数指定池的大小。
当您在单个节点上运行并且只有一个地图阶段时,我建议您将“map_js_vm_count”参数设置为您的环的大小,默认情况下为64.更深入的描述{{ 3}}。
虽然地图阶段处理可以轻松并且并行完成,但是中央减少阶段很容易成为瓶颈,因为它在单个节点上递归运行。这可以是can be found here的地址。启用预缩减将允许缩减阶段的第一次迭代并行运行,这很可能会提高作业的效率。但是,您需要通过增加'reduce_js_vm_count'参数来增加可用于减少相位函数的VM数量。
如果同时运行大型MapReduce作业,支持此操作所需的JavaScript VM数量可能会变得非常大。通常鼓励将映射和减少阶段函数转换为Erlang,因为它确实消除了JS VM争用,并且由于较少的VM相关开销而表现更好。对于您打算定期运行的MapReduce作业,始终建议这样做。