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=20000,2.4版本及以前版本最大不能超過這個數值,2.6版本(開發版2.5版本)取消這個限制。 相關鏈接http://nosqldb.org/topic/50ca8a50ee680fee790001f2
什么原因導致連接數過高
-
連接池配置不合理 分片情況下,現象是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.
代碼: https://github.com/mongodb/mongo/commit/706459a8af0b278609d70e7122595243df6aeee8 https://github.com/mongodb/mongo/commit/74323d671a216c8c87fcb295ed743f830d5212ee https://github.com/mongodb/mongo/commit/5d5fe49dfb5f452832b9d44fddbfb2a4e8b42f2a
=============== - connPoolTimeout設置
(該參數不在官方沒有) 效果
mongos> db.runCommand({ setParameter : 1, connPoolTimeout : 900 })
{ "was" : 1800, "ok" : 1 }
初步測試,效果不明顯。
- releaseConnections
計划添加個命令releaseConnections,從mongod運行,減少復制集連接數
