Mongo mapReduce 伴娘超过三次怎么化解16M怎么解

博客分类:
来,我给你们看一段神奇的mongodb的mapreduce操作!
首先我们执行一段js,用来往mongodb数据库里插入几条记录:
//insert.js
for(var i=0;i&5;i++){
db.RegistRecord.save({"ip":"11.11.11.11","account":"ongyong"});
for(var i=0;i&2;i++){
db.RegistRecord.save({"ip":"11.11.11.22","account":"ongyong22"});
for(var i=0;i&1;i++){
db.RegistRecord.save({"ip":"11.11.11.33","account":"ongyong33"});
没有问题,随后我们来使用mongodb的mapreduce来进行一个统计,统计同一ip在记录里出现的次数,很简单的mapreduce入门例子,写法如下,不多解释。
//regmp.js
printjson("job start");
var map = function() {
emit(this.ip, {value: 1});
var reduce = function(key, values) {
var count = 0;
values.forEach(function(v) {
count += v['value'];
return {count: count };
var res = db.runCommand({mapreduce:"RegistRecord",map:map, reduce:reduce, out:"log_results"});
printjson("job end")
然后我们执行这个js脚本。
我们看结果:
"_id" : "11.11.11.11",
"value" : {
"count" : 5.0
"_id" : "11.11.11.22",
"value" : {
"count" : 2.0
"_id" : "11.11.11.33",
"value" : {
"value" : 1.0
OK,运算结果正确,各ip分别出现了5次,2次,1次。
OK,到这里,如果你认为我就是要为了演示这个东西,那我肯定是来找喷的,哥们儿,这特么一点也不神奇。神奇的事情在下面,我们继续看:
当我们把记录数增加到某一个量级,(如2000)
//insert.js
for(var i=0;i&2000;i++){
db.RegistRecord.save({"ip":"11.11.11.11","account":"ongyong"});
for(var i=0;i&2;i++){
db.RegistRecord.save({"ip":"11.11.11.22","account":"ongyong22"});
for(var i=0;i&1;i++){
db.RegistRecord.save({"ip":"11.11.11.33","account":"ongyong33"});
然后我们再次执行regmp.js这段代码运行mapreduce,注意,绝对没有任何改动,这时,神奇的事情出现了,看结果:
"_id" : "11.11.11.11",
"value" : {
"count" : NaN
"_id" : "11.11.11.22",
"value" : {
"count" : 2.0
"_id" : "11.11.11.33",
"value" : {
"value" : 1.0
11.11.11.11这个ip的结果出现了一个非数值型字符串!!!而其余两个正确。神奇啊!不明白啊!困惑啊!!
然而,我得找原因啊,我想知道,到底在经过map函数后,reduce函数接受到的values的格式是怎样的,我稍微改了下reduce函数,我不进行任何操作,直接把value作为结果保存。
改动后的Reduce函数如下:
var reduce = function(key, values) {
return {count: values };
首先,看记录数各为:5,2,1时,经过map函数处理,然后传给reduce函数的参数格式如下:
"_id" : "11.11.11.11",
"value" : {
"count" : [{
"value" : 1.0
"value" : 1.0
"value" : 1.0
"value" : 1.0
"value" : 1.0
"_id" : "11.11.11.22",
"value" : {
"count" : [{
"value" : 1.0
"value" : 1.0
"_id" : "11.11.11.33",
"value" : {
"value" : 1.0
没有问题!传到reduce函数中的value是一个固定格式的json串。我们可以对count中的各元素进行数值运算。
然后,我们看记录数为2000的,结果:
"_id" : "11.11.11.22",
"value" : {
"count" : [{
"value" : 1.0
"value" : 1.0
"_id" : "11.11.11.33",
"value" : {
"value" : 1.0
"_id" : "11.11.11.11",
"value" : {
"count" : [{
"count" : [{
"value" : 1.0
"value" : 1.0
"value" : 1.0
。。。。此处省略后面记录
看!!!最后这条记录!瞎了吧!!!传过来的values值的结构都改变了!!!无缘无故的嵌套了几层count,再用
count += v['value']当然没法进行数值运行啦!!!坑爹啊!!!为什么???
Mongodb版本 2.0.1 ,32bit
环境:windowxp 32bit
(少废话,我生产环境当然是用的linux,我这不是做实验么)
我要吃晚饭了先,linux环境我稍后回来继续做~
请问下,& 你这个问题最终解决了没? 剧透下呗? 解决了,你看我另一篇文章就明白啦
浏览: 442238 次
来自: 北京
谢谢分享。。。
我的配置是这样的:&!-- ActiveMQ 连接工厂
ERROR 8976 --- [erContainer#2-1 ...
你好,为什么我启动报错呢setClientID call no ...
写的很详细谢谢---
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'MongoDB GroupBy操作& 结果集大小限制问题&
公司是做互联网广告投放的,需要统计广告展现量在前五百的域名。最简单粗暴的做法就是group by,根据url分组,然后再sort一下就搞定晒!结果问题就出现了。
如下统计的当日22时的日志,文档数量:904405。
db['log._22'].group({
key : {domainUrl:1},
initial : {count:0},
reduce : function Reduce(doc, out) {
out.count++;
Error in executing GroupBy
Command 'group' failed: exception: group() can't handle more than 20000 unique keys (response: { "errmsg" : "exception: group() can't handle more than 20000 unique keys", "code" : 17203, "ok" : 0.0 })
Type: MongoDB.Driver.MongoCommandException
错误信息不够具体,加之理解问题,我以为是集合中的文档数量不能超过20000,2万都不能支持那要group干嘛。经过多次测试,终于证明了我是错的。是不支持大于2万的结果集,即分组后产生的文档数量不能超过2万。
//集合大小
& db['log._22'].count();
//唯一url数量
& db['log._22'].distinct('domainUrl').
这个集合中的唯一url数量是20738,刚好超过了2万,所以MongoDB的group就无能为力了。
另外测试还意外发现,distinct对结果集大小也是有限制的。结果集大小不能超过16Mb。
& db['log._22'].distinct('webUrl').
distinct failed: {
"errmsg" : "exception: distinct too big, 16mb cap",
"code" : 17217,
MongoDB为什么这么多限制,而且阈值都比较小,还请大神指点。
问题是用来解决的,通过stackoverflow大神的指点,我尝试着用MongoDB的mapreduce搞定它,其实一开始我是拒绝的,因为,你不能让我用,我就用;首先,我要看一下我会不会用。结果发现,我不会用,然后看了看MongoDB的说明文档。写出如下代码:
db.runCommand({ mapreduce: "log._22",
map : function Map() {
uuid:this.adUUId, //对不同的广告统计url
url:this.domainUrl
{count: 1}
reduce : function Reduce(key, values) {
var total=0;
for( var i in values){
total +=values[i].
return {count:total};
finalize : function Finalize(key, reduced) {
out : { inline : 1 }
我用了一次,感觉效果还不错。现在也推荐给你试一下。
结果对象的结构如下:
{ "_id" : { "uuid" : "inmobi" , "url" : "static.51y5.net" } , "value" : { "count" : 82409.0}}
{ "_id" : { "uuid" : "inmobi" , "url" : ""} , "value" : { "count" : .23714.0}}
_id属性中是分组字段,value属性中保存结果对象。mongodb聚合函数产生的count是double类型的。你可以在finalize方法中处理一下,转换成整型。我是在java 代码转换的。
MongoDB的Mapreduce我也是第一次用,更具体的用法详解,待我研究之后,再做报告。因为我不愿意写完以后,再加点特技上去,文章“duang”一下,很赞,很劲,这样读者出来一定会骂我,博主根本就是不会,还装逼。(just kidding.)
以上内容有不对的地方,还望大家指正,虚心学习。
Thanks a lot ,END!
Copyright (C) , All Rights Reserved.
版权所有 闽ICP备号
processed in 0.036 (s). 13 q(s)9被浏览563分享邀请回答0添加评论分享收藏感谢收起MongoDB 连接数高产生原因及解决 - 为程序员服务
MongoDB 连接数高产生原因及解决
Sharding架构下连接数很容易达到很高,这里连接数分为几个概念:
tcp 连接数 netstat可以统计的,一般这个是最高.如果mongod/mongos在同一台服务器,更明显。
参考命令:netstat -ant|awk ‘{print $5}’ |awk -F: ‘{print $1}’|sort |uniq -c|sort -rn
mongos/mongod 连接数 mongostat/db.serverStatus()/connPoolStats可统计。
连接数多高算高呢?
这要看连接到mongodb集群应用服务器实例数、qps(增删改查)等判断。
应用服务器单台,如果qps&100, ,mongos连接数超过2000,肯定是高了。这一般是由于连接池配置不合理导致。
mongod/mongos 默认最大连接数maxConns=2版本及以前版本最大不能超过这个数值,2.6版本(开发版2.5版本)取消这个限制。
什么原因导致连接数过高
连接池配置不合理
分片情况下,现象是tcp 连接数过高(如达到20000),mongos连接数过高(如超过10000)
java为例,connectionsPerHost 不宜配置过大,官方默认值由原来10改成100了,而且有默认5倍的乘数(threadsAllowedToBlockForConnectionMultiplier),一般20~50就可以了。
应用服务器实例过多
我们遇到的场景,当连接到mongos的应用服务器(如Tomcat实例数量)过百,甚至达到近200台时,tcp连接数超高,达到15000以上,查看mongod对应端口连接数高达8000多,mongos 2000多。此时ops(query,insert,update,delete)低于200每秒,。定期重启(如一周一次)mongos可适当缓解该问题。
mongodb本身的原因表现为mongos连接数不高(如1000+),mongod连接数比较高(如8000+)。
总结一下,连接数高分为几个场景:
应用服务器实例过多,可统计每个实例建立的连接数,适当调低连接池参数。
mongos连接数高,这种就是配置的问题,更改连接池参数。
mongos连接数不高,mongod连接数比较高,如超过5000,如果连接池配置合理还比较高的话,尝试启用releaseConnectionsAfterResponse参数(2.2.4版本以上),该参数为
隐藏参数releaseConnectionsAfterResponse
mongos& use admin
switched to db admin
mongos& db.runCommand({ setParameter : 1, releaseConnectionsAfterResponse : true }){ "was" : false, "ok" : 1 }
shell& mongos --setParameter "releaseConnectionsAfterResponse=true" --configdb ...
该参数注意事项:
写操作需要立即调用getLastError (w=1,即安全写模式),w=2(等待从库写确认)的时候可能会有些错误。
升级过后,或者重启mongos进程后,需要重新设置该参数,该参数只对单个mongos生效。
启用releaseConnectionsAfterResponse 参数,tcp 连接数明显降低到比较稳定数目。几个小时,tcp连接数从8000多降到4000多,效果不错。
releaseConnectionsAfterResponse 参数原理
通常,对于每个mongos-&mongod连接是单独缓存的,并且该连接不能重复使用,即使该连接是空闲时也是如此,一直到连接关闭连接回到连接池中才能再使用;releaseConnectionsAfterResponse 参数启用后,mongos-&mongod之间的连接在完成一个读操作或者安全写操作后能够重复使用(把连接放到连接池中而不是缓存,即更早的回归到连接池中),releaseConnectionsAfterResponse参数简单讲就是mongos-&mongod的连接更早的回到连接池中,这样就不会开太多的连接了,从而减少连接数。
Create a new serverParameter for mongos, “releaseConnectionsAfterResponse,” which enables returning ShardConnections from the per-socket pool to the global pool after each read operation. This should reduce the total number of outgoing mongos connections to each shard.
the option allows better use of the connection pool, it doesn’t invalidate the connections in the pool. Normally, mongos-&mongod connections for insert/update/delete/query are cached individually for each incoming connection, and can’t be re-used until the incoming connection is closed, even if they are idle and there are other active incoming connections.
What the releaseConnectionsAfterResponse option does is allow the mongos-&mongod connection to be re-used (returned to the pool) after any read op (including getLastError(), so after safe writes as well). It shouldn’t have a significant performance impact – the connection isn’t destroyed, it’s just returned from the incoming connection cache to the shared pool early.
===============
- connPoolTimeout设置
(该参数不在官方没有)
mongos& db.runCommand({ setParameter : 1, connPoolTimeout : 900 }){ "was" : 1800, "ok" : 1 }
初步测试,效果不明显。
releaseConnections
计划添加个命令releaseConnections,从mongod运行,减少复制集连接数。
记录我的程序员之路
原文地址:, 感谢原作者分享。
您可能感兴趣的代码

我要回帖

更多关于 伴娘超过三次怎么化解 的文章

 

随机推荐