分类: NOSQL
2018-11-06 21:53:44
原文地址:破解MongoDB分片集群高连接数之迷 作者:horizonhyg
初步来看,当连接空闲时间超过1800秒即30分钟才会释放连接。于是我们想调低该值会不会解决问题?
如何解决
发现不是就我们遇到该问题,github上已经有了个pull request。
通过添加“maxSpareConnPools" "connPoolTimeout”两个参数来对连接池更细粒度的控制。
"maxSpareConnPools" option was abolished.
"connPoolMaxPerHost" is available instead
相关bug:
官方对该解决方案目前没有接受,官方目前的解决方案是添加了一个参数(2.2.4版本以上),该参数为隐藏参数releaseConnectionsAfterResponse ,版本2.2.4, 2.4.2, 2.5.0 。
mongos> use admin switched to db admin mongos> db.runCommand({ setParameter : 1, releaseConnectionsAfterResponse : true })
mongos> { "was" : false, "ok" : 1 }或者
shell> mongos --setParameter "releaseConnectionsAfterResponse=true" --configdb ...
该参数注意事项:
写操作需要立即调用getLastError (w=1,即安全写模式),w=2(等待从库写确认)的时候可能会有些错误。
升级过后,或者重启mongos进程后,需要重新设置该参数,该参数只对单个mongos生效。
代码:
方案
这两个方案需要进一步验证,检验是否能解决高连接数问题。
启用releaseConnectionsAfterResponse 参数,tcp 连接数明显降低到比较稳定数目。几个小时,tcp连接数从8000多降到4000多,效果不错。
通常,对于每个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.
(该参数不在官方没有)
效果
mongos> db.runCommand({ setParameter : 1, connPoolTimeout : 900 }) { "was" : 1800, "ok" : 1 }