日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mongo连接分析

發(fā)布時間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongo连接分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

摘要

在前面的文章中有分析過關(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操作流程

public static void main(final String[] args) {try {final String host = "localhost";// 連接配置屬性final MongoClientOptions clientOptions = new MongoClientOptions.Builder().writeConcern(WriteConcern.ACKNOWLEDGED).readPreference(ReadPreference.secondaryPreferred()).connectionsPerHost(10).socketTimeout(5000).build();final List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();final String str = "test";final char[] psd = str.toCharArray();final MongoCredential credential = MongoCredential.createCredential("test","test",psd);credentialsList.add(credential);final ServerAddress address = new ServerAddress(host, 27017);//包含了一個內(nèi)置的數(shù)據(jù)庫連接池final MongoClient client = new MongoClient(address, credentialsList, clientOptions);final DB db = client.getDB("test");final DBCollection postCollection = db.getCollection("test");postCollection.findOne();//連接關(guān)閉,釋放資源client.close();} catch (final UnknownHostException e) {e.printStackTrace();}}

這只是一個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)用性能,阻塞其他操作

private int minConnectionsPerHost; //每個節(jié)點的最小連接數(shù) private int connectionsPerHost = 100; // 每個節(jié)點的連接數(shù)private int threadsAllowedToBlockForConnectionMultiplier = 5; //最大等待線程private int maxWaitTime = 1000 * 60 * 2; // 獲取連接最大等待時間private int maxConnectionIdleTime; // 連接池最大空閑時間private int maxConnectionLifeTime;private int connectTimeout = 1000 * 10; // 連接最大時間private int socketTimeout = 0; // 操作最大時間private boolean socketKeepAlive = false;private boolean autoConnectRetry = false;private long maxAutoConnectRetryTime = 0;// 心跳檢測,保持TCP連接private int heartbeatFrequency = Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalMS", "5000"));private int minHeartbeatFrequency = Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalNoMasterMS", "500"));private int heartbeatConnectTimeout = Integer.parseInt(System.getProperty("com.mongodb.updaterConnectTimeoutMS", "20000"));private int heartbeatSocketTimeout = Integer.parseInt(System.getProperty("com.mongodb.updaterSocketTimeoutMS", "20000"));

可以和關(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é)

以上是生活随笔為你收集整理的mongo连接分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。