摘要:本文旨在梳理這些問題,進(jìn)行一個(gè)全面的分析。等到進(jìn)行數(shù)據(jù)庫(kù)操作的時(shí)候,再去中獲取一個(gè)連接,進(jìn)行操作總結(jié)通過以上分析,對(duì)于以下的數(shù)據(jù)庫(kù)連接池與關(guān)系型數(shù)據(jù)庫(kù)連接池并無(wú)區(qū)別。
摘要
在前面的文章中有分析過關(guān)系型數(shù)據(jù)庫(kù)的連接,以及連接池的原理。在mongo數(shù)據(jù)庫(kù)同樣存在,經(jīng)常看到有網(wǎng)友在問mongo 連接了數(shù)據(jù)庫(kù)要不要關(guān),怎么關(guān)。內(nèi)置的數(shù)據(jù)庫(kù)連接池是單線程還是多線程,mongo服務(wù)器為什么會(huì)殺游標(biāo),殺連接諸如此類的問題,其實(shí)這類問題基本上就是連接池的問題,而很多和關(guān)系型數(shù)據(jù)庫(kù)是類似的,并不是mongo獨(dú)有的。
本文旨在梳理這些問題,進(jìn)行一個(gè)全面的分析。
客戶端連接通過driver jar去連接,以java為例,通過mongo-java-driver
連接mongo,這一點(diǎn)和關(guān)系型數(shù)據(jù)庫(kù)一樣,不同的是關(guān)系型數(shù)據(jù)庫(kù)有一套標(biāo)準(zhǔn)的阻塞型的,寫入JDK的數(shù)據(jù)庫(kù)操作實(shí)現(xiàn),即JDBC。而mongo則是完全有driver提供。在mongo-java-driver 3.0版本之前只提供了同步的driver操作,3.x之后開始提供異步的driver操作,這邊不做擴(kuò)散,后續(xù)會(huì)有相關(guān)博文介紹異步的數(shù)據(jù)庫(kù)操作,本文只介紹同步driver操作。
數(shù)據(jù)庫(kù)操作
一個(gè)基于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 ListcredentialsList = new ArrayList (); 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); //包含了一個(gè)內(nèi)置的數(shù)據(jù)庫(kù)連接池 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(); } }
這只是一個(gè)sample 實(shí)際應(yīng)用中,MongoClient在一個(gè)jvm中只應(yīng)該有一個(gè)實(shí)例,由他管理連接,進(jìn)行數(shù)據(jù)庫(kù)操作。
client與數(shù)據(jù)庫(kù)的交互,mongo 協(xié)議也是基于TCP的
幾個(gè)重要的類
MongoClientOptions: 數(shù)據(jù)庫(kù)連接配置項(xiàng)
DB: database連接
DBCollection: collection操作
所以mongo連接的配置核心就在于MongolientOptions類了。比較重要的配置就是
connectionsPerHost,對(duì)于線上環(huán)境,如果連接數(shù)據(jù)庫(kù)的應(yīng)用比較多,這個(gè)連接數(shù)不宜過大
socketTimeout: 數(shù)據(jù)庫(kù)操作超時(shí)時(shí)間,一般5s中,對(duì)于慢操作,不應(yīng)該一直占用連接,會(huì)損害應(yīng)用性能,阻塞其他操作
private int minConnectionsPerHost; //每個(gè)節(jié)點(diǎn)的最小連接數(shù)
private int connectionsPerHost = 100; // 每個(gè)節(jié)點(diǎn)的連接數(shù) private int threadsAllowedToBlockForConnectionMultiplier = 5; //最大等待線程 private int maxWaitTime = 1000 * 60 * 2; // 獲取連接最大等待時(shí)間 private int maxConnectionIdleTime; // 連接池最大空閑時(shí)間 private int maxConnectionLifeTime; private int connectTimeout = 1000 * 10; // 連接最大時(shí)間 private int socketTimeout = 0; // 操作最大時(shí)間 private boolean socketKeepAlive = false; private boolean autoConnectRetry = false; private long maxAutoConnectRetryTime = 0; // 心跳檢測(cè),保持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ù)庫(kù)連接池的實(shí)現(xiàn)對(duì)比一下
initialSize:初始連接數(shù)
maxActive: 最大連接數(shù)量
minIdle: 最小連接數(shù)量
maxWait: 獲取連接最大等待時(shí)間ms
minEvictableIdleTimeMillis:連接保持空閑而不被驅(qū)逐的最小時(shí)間
timeBetweenEvictionRunsMillis:銷毀線程的時(shí)間檢測(cè)
testOnBorrow:申請(qǐng)連接時(shí)執(zhí)行,比較影響性能
validationQuery:testOnBorrow為true檢測(cè)是否是有效連接sql
testWhileIdle:申請(qǐng)連接的時(shí)候檢測(cè)
mongo 內(nèi)置的連接池管理比較簡(jiǎn)單,沒有進(jìn)行連接池的連接有效管理,通過heartbeat間隔一段時(shí)間發(fā)送數(shù)據(jù)包給mongo 服務(wù)器,確保連接有效,這一點(diǎn)和之前介紹的有點(diǎn)區(qū)別,之前的銷毀掉無(wú)用的連接。這樣會(huì)增加額外的網(wǎng)絡(luò)和CPU負(fù)擔(dān)。
看下mongo 創(chuàng)建MongoClient的時(shí)候會(huì)去初始化連接池。等到進(jìn)行數(shù)據(jù)庫(kù)操作的時(shí)候,再去PooledConnectionProvider中獲取一個(gè)連接,進(jìn)行操作
通過以上分析,對(duì)于mongo driver 3.x 以下的mongo數(shù)據(jù)庫(kù)連接池與關(guān)系型數(shù)據(jù)庫(kù)連接池并無(wú)區(qū)別。只是連接池的實(shí)現(xiàn)方式不一樣,比如一個(gè)用鎖,一個(gè)用信號(hào)量。容器的選型也不太一樣,但是這些并不會(huì)影響到大部分的應(yīng)用開發(fā)者對(duì)于連接的配置和理解。回到開頭提出的幾個(gè)問題,看到這里自然就有答案了。而對(duì)于服務(wù)器kill掉游標(biāo)這個(gè)問題,游標(biāo)本身也不是mongo獨(dú)有的,客戶端通過游標(biāo)控制結(jié)果數(shù)量的讀取,游標(biāo)本身也是占用不少資源的,所以不能一直占有,服務(wù)器kill掉游標(biāo),所以游標(biāo)占用時(shí)間太長(zhǎng)。可以通過db.serverStatus().metrics.cursor去查看timeout的游標(biāo),找出耗時(shí)操作,進(jìn)行優(yōu)化。
"cursor": { "timedOut": "NumberLong(99)" "open": { "noTimeout": "NumberLong(0)" "pinned": "NumberLong(3)" "total": "NumberLong(3)" } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/19259.html
摘要:推薦閱讀資源庫(kù)工具應(yīng)用程序精選列表中文版有哪些鮮為人知,但是很有意思的網(wǎng)站一份攻城獅筆記每天搜集上優(yōu)秀的項(xiàng)目一些有趣的民間故事超好用的谷歌瀏覽器油猴插件合集目錄資源文檔文章圖書會(huì)談教程更多庫(kù)工具管理數(shù)據(jù)部署桌面發(fā)展監(jiān)控應(yīng)用資源文檔介紹文檔教 推薦閱讀 MongoDB 資源、庫(kù)、工具、應(yīng)用程序精選列表中文版 有哪些鮮為人知,但是很有意思的網(wǎng)站? 一份攻城獅筆記 每天搜集 Github ...
摘要:出現(xiàn)的問題筆者前段時(shí)間開發(fā)一個(gè)新項(xiàng)目的某個(gè)功能模塊要讀取老游戲中某個(gè)數(shù)據(jù)庫(kù)計(jì)作庫(kù)連續(xù)讀庫(kù)中的個(gè)集合相當(dāng)于的張表取數(shù)據(jù)在測(cè)試環(huán)境單次操作時(shí)是內(nèi)但是并發(fā)測(cè)試情況下比如內(nèi)個(gè)并發(fā)時(shí)讀取庫(kù)個(gè)集合的耗時(shí)能達(dá)到以上甚至且個(gè)并發(fā)請(qǐng)求幾乎同時(shí)完成但是在我本地 出現(xiàn)的問題 筆者前段時(shí)間開發(fā)一個(gè)新項(xiàng)目的某個(gè)功能模塊,要讀取老游戲中某個(gè)Mongo數(shù)據(jù)庫(kù)(計(jì)作A庫(kù)),連續(xù)讀A庫(kù)中的6個(gè)集合(相當(dāng)于MySQL的6...
摘要:簡(jiǎn)介在我的前一篇小文中小書提到了可以更換會(huì)話儲(chǔ)存那么這篇文章我們就來(lái)講講在進(jìn)行會(huì)話管理的時(shí)候如何將會(huì)話數(shù)據(jù)保存在外部數(shù)據(jù)庫(kù)中本文中我們使用用作會(huì)話儲(chǔ)存數(shù)據(jù)庫(kù)本文中使用的模塊以及版本號(hào)一覽模塊名稱版本號(hào)特性支持支持所有版本的支持支持 簡(jiǎn)介 在我的前一篇小文中express-session小書提到了express-session可以更換會(huì)話儲(chǔ)存. 那么這篇文章我們就來(lái)講講express在進(jìn)...
摘要:簡(jiǎn)介在我的前一篇小文中小書提到了可以更換會(huì)話儲(chǔ)存那么這篇文章我們就來(lái)講講在進(jìn)行會(huì)話管理的時(shí)候如何將會(huì)話數(shù)據(jù)保存在外部數(shù)據(jù)庫(kù)中本文中我們使用用作會(huì)話儲(chǔ)存數(shù)據(jù)庫(kù)本文中使用的模塊以及版本號(hào)一覽模塊名稱版本號(hào)特性支持支持所有版本的支持支持 簡(jiǎn)介 在我的前一篇小文中express-session小書提到了express-session可以更換會(huì)話儲(chǔ)存. 那么這篇文章我們就來(lái)講講express在進(jìn)...
閱讀 2320·2021-11-08 13:13
閱讀 1250·2021-10-09 09:41
閱讀 1693·2021-09-02 15:40
閱讀 3193·2021-08-17 10:13
閱讀 2551·2019-08-29 16:33
閱讀 3126·2019-08-29 13:17
閱讀 3137·2019-08-29 11:00
閱讀 3301·2019-08-26 13:40