mongo连接分析
摘要
在前面的文章中有分析過關(guān)系型數(shù)據(jù)庫的連接,以及連接池的原理。在mongo數(shù)據(jù)庫同樣存在,經(jīng)??吹接芯W(wǎng)友在問mongo 連接了數(shù)據(jù)庫要不要關(guān),怎么關(guān)。內(nèi)置的數(shù)據(jù)庫連接池是單線程還是多線程,mongo服務(wù)器為什么會殺游標(biāo),殺連接諸如此類的問題,其實這類問題基本上就是連接池的問題,而很多和關(guān)系型數(shù)據(jù)庫是類似的,并不是mongo獨有的。
本文旨在梳理這些問題,進行一個全面的分析。
Client 連接分析
客戶端連接通過driver jar去連接,以java為例,通過mongo-java-driver
連接mongo,這一點和關(guān)系型數(shù)據(jù)庫一樣,不同的是關(guān)系型數(shù)據(jù)庫有一套標(biāo)準(zhǔn)的阻塞型的,寫入JDK的數(shù)據(jù)庫操作實現(xiàn),即JDBC。而mongo則是完全有driver提供。在mongo-java-driver 3.0版本之前只提供了同步的driver操作,3.x之后開始提供異步的driver操作,這邊不做擴散,后續(xù)會有相關(guān)博文介紹異步的數(shù)據(jù)庫操作,本文只介紹同步driver操作。
數(shù)據(jù)庫操作
一個基于mongo-java-driver-2.14.x的mongo操作流程
這只是一個sample 實際應(yīng)用中,MongoClient在一個jvm中只應(yīng)該有一個實例,由他管理連接,進行數(shù)據(jù)庫操作。
client與數(shù)據(jù)庫的交互,mongo 協(xié)議也是基于TCP的
幾個重要的類
MongoClientOptions: 數(shù)據(jù)庫連接配置項
DB: database連接
DBCollection: collection操作
所以mongo連接的配置核心就在于MongolientOptions類了。比較重要的配置就是
connectionsPerHost,對于線上環(huán)境,如果連接數(shù)據(jù)庫的應(yīng)用比較多,這個連接數(shù)不宜過大
socketTimeout: 數(shù)據(jù)庫操作超時時間,一般5s中,對于慢操作,不應(yīng)該一直占用連接,會損害應(yīng)用性能,阻塞其他操作
可以和關(guān)系型數(shù)據(jù)庫連接池的實現(xiàn)對比一下
initialSize:初始連接數(shù)maxActive: 最大連接數(shù)量
minIdle: 最小連接數(shù)量
maxWait: 獲取連接最大等待時間ms
minEvictableIdleTimeMillis:連接保持空閑而不被驅(qū)逐的最小時間
timeBetweenEvictionRunsMillis:銷毀線程的時間檢測
testOnBorrow:申請連接時執(zhí)行,比較影響性能
validationQuery:testOnBorrow為true檢測是否是有效連接sql
testWhileIdle:申請連接的時候檢測
mongo 內(nèi)置的連接池管理比較簡單,沒有進行連接池的連接有效管理,通過heartbeat間隔一段時間發(fā)送數(shù)據(jù)包給mongo 服務(wù)器,確保連接有效,這一點和之前介紹的有點區(qū)別,之前的銷毀掉無用的連接。這樣會增加額外的網(wǎng)絡(luò)和CPU負擔(dān)。
看下mongo 創(chuàng)建MongoClient的時候會去初始化連接池。等到進行數(shù)據(jù)庫操作的時候,再去PooledConnectionProvider中獲取一個連接,進行操作
總結(jié)
通過以上分析,對于mongo driver 3.x 以下的mongo數(shù)據(jù)庫連接池與關(guān)系型數(shù)據(jù)庫連接池并無區(qū)別。只是連接池的實現(xiàn)方式不一樣,比如一個用鎖,一個用信號量。容器的選型也不太一樣,但是這些并不會影響到大部分的應(yīng)用開發(fā)者對于連接的配置和理解。回到開頭提出的幾個問題,看到這里自然就有答案了。而對于服務(wù)器kill掉游標(biāo)這個問題,游標(biāo)本身也不是mongo獨有的,客戶端通過游標(biāo)控制結(jié)果數(shù)量的讀取,游標(biāo)本身也是占用不少資源的,所以不能一直占有,服務(wù)器kill掉游標(biāo),所以游標(biāo)占用時間太長??梢酝ㄟ^db.serverStatus().metrics.cursor去查看timeout的游標(biāo),找出耗時操作,進行優(yōu)化。
"cursor": { "timedOut": "NumberLong(99)" "open": { "noTimeout": "NumberLong(0)" "pinned": "NumberLong(3)" "total": "NumberLong(3)" } } 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
- 上一篇: 物联网和前端技术,两者相辅相成并且互相促
- 下一篇: 异地取数