MongoDB開發(fā)系列-復(fù)制集對(duì)程序開發(fā)的影響

本篇文章主要從以下幾個(gè)方面說(shuō)明復(fù)制集架構(gòu)對(duì)程序開發(fā)的影響

筆者把基于MongoDb的應(yīng)用開發(fā)分為軟件運(yùn)維和 軟件開發(fā)兩個(gè)階段

本篇會(huì)側(cè)重后一階段的實(shí)踐經(jīng)驗(yàn)分享

1 理解復(fù)制集與主從結(jié)構(gòu)

2 關(guān)注數(shù)據(jù)庫(kù)連接字符串

復(fù)制集的基本概念

談到復(fù)制集,它是副本的集合,分布式系統(tǒng)的基本屬性之一。

副本(Replica)是分布式系統(tǒng)最常見的概念之一,指分布式系統(tǒng)對(duì)數(shù)據(jù)和服務(wù)提供的一種冗余方式。在常見的分布式系統(tǒng)中,為了對(duì)外提供高可用的服務(wù),我們往往會(huì)對(duì)數(shù)據(jù)和服務(wù)進(jìn)行副本處理。有副本的概念,就會(huì)關(guān)聯(lián)到副本數(shù)據(jù)一致性問題。

MongoDb環(huán)境下,我們很容易從公開資料查詢到復(fù)制集的基本你含義

MongoDB 復(fù)制(副本集)MongoDB復(fù)制是將數(shù)據(jù)同步在多個(gè)服務(wù)器的過程。

復(fù)制提供了數(shù)據(jù)的冗余備份,并在多個(gè)服務(wù)器上存儲(chǔ)數(shù)據(jù)副本,提高了數(shù)據(jù)的可用性, 并可以保證數(shù)據(jù)的安全性。

復(fù)制還允許您從硬件故障和服務(wù)中斷中恢復(fù)數(shù)據(jù)

副本集角色

MongoDB副本集是一組mongod進(jìn)程的集合,它通過一系列機(jī)制實(shí)現(xiàn)了高可用。

mongod?is the primary daemon process for the MongoDB system. It handles data requests, manages data access, and performs background management operations.

副本集角色主要包括主節(jié)點(diǎn),從節(jié)點(diǎn),和仲裁節(jié)點(diǎn)。 主節(jié)點(diǎn)負(fù)責(zé)所有的寫操作。


復(fù)制集與主從結(jié)構(gòu)的關(guān)系

兩者屬于不同的MongoDb數(shù)據(jù)庫(kù)結(jié)構(gòu),主從結(jié)構(gòu)已經(jīng)不被官方推薦

Deprecated since version 3.6:?MongoDB 3.6 deprecates the use of master-slave replication.Master-slave replication has been deprecated for components of sharded clusters since MongoDB 3.2.

主從結(jié)構(gòu)與復(fù)制集最主要的區(qū)別是前者有真正的主服務(wù)器的概念,復(fù)制集沒有主服務(wù)器的概念,通過選舉選出主要的主節(jié)點(diǎn)Primary

Do not run an arbiter on systems that also host the primary or the secondary members of the replica set

仲裁者一定要部署在獨(dú)立的服務(wù)器上,避免與主節(jié)點(diǎn)和復(fù)制節(jié)點(diǎn)部署在一起

傳統(tǒng)的主從部署


復(fù)制集

這是Mongo官方更推薦的部署結(jié)構(gòu)


復(fù)制集


關(guān)注數(shù)據(jù)庫(kù)連接字符串

復(fù)制集屬于MongoDb高可用架構(gòu)的一種部署方式,對(duì)于使用數(shù)據(jù)庫(kù)的應(yīng)用者來(lái)說(shuō)應(yīng)該是極度透明的,內(nèi)部主從實(shí)例切換應(yīng)該做到無(wú)感切換,也就是說(shuō)應(yīng)用并不關(guān)心具體的一次數(shù)據(jù)庫(kù)操作,是由哪個(gè)實(shí)例來(lái)處理的。

我們可以在程序中指定如何連接復(fù)制集,正確的連接方式可以避免當(dāng)主節(jié)點(diǎn)宕機(jī)或者故障時(shí),應(yīng)用程序無(wú)感知正常切換,借用網(wǎng)絡(luò)的一張圖來(lái)說(shuō)明


這張圖的左邊部分實(shí)際上是有問題的,直連一個(gè)實(shí)例,并且標(biāo)明Primary,對(duì)于連接Db數(shù)據(jù)庫(kù)的Driver來(lái)說(shuō),它應(yīng)該不用關(guān)心哪個(gè)實(shí)例是主,并且哪個(gè)實(shí)例是主也是會(huì)變化的。

試想運(yùn)維給到開發(fā)的數(shù)據(jù)庫(kù)連接串是一組配置,那我們?nèi)绾渭傻綉?yīng)用程序中?

基礎(chǔ)設(shè)置

對(duì)于PHP應(yīng)用來(lái)講,框架使用YII2,驅(qū)動(dòng)使用yii2-mongodb

https://www.yiiframework.com/extension/yiisoft/yii2-mongodb

Github地址

https://github.com/yiisoft/yii2-mongodb

安裝

Either run

php composer.phar require --prefer-dist yiisoft/yii2-mongodb

or add

"yiisoft/yii2-mongodb": "~2.1.0"

連接字符串

直連方式

return [

? ? 'class' => '\yii\mongodb\Connection',

? ? 'dsn'? => 'mongodb://username:password@s1.test.mongodb.domain.cn:10000/databasename',

? ? 'options'=>[

? ? ? ? 'socketTimeoutMS' => 1000

? ? ]

];

復(fù)制集連接

return [

'class' => '\yii\mongodb\Connection',

'dsn' => 'mongodb://user:pqssword@s1._test.mongodb.domain.cn:30000,s2.mongodb.domain.cn:30000,s3._test.mongodb.domain.cn:30000/databasename',

];

問題來(lái)了

1 應(yīng)該都連接,還是只連接一臺(tái)數(shù)據(jù)庫(kù)實(shí)例即可?

生產(chǎn)環(huán)境下,復(fù)制集合實(shí)例有3個(gè),我們都配到了連接串中。是否應(yīng)該只連接一臺(tái),我個(gè)人也沒有很好的解釋,理論上應(yīng)用只需要一個(gè)入口即可,后續(xù)都交給數(shù)據(jù)庫(kù)處理。

2 連接超時(shí)設(shè)置是否應(yīng)該顯示設(shè)置?

https://docs.mongodb.com/manual/reference/connection-string/?官方有針對(duì)連接串的參考說(shuō)明。

談到超時(shí)問題,我們來(lái)看數(shù)據(jù)庫(kù)連接周期

一次完整的請(qǐng)求包括三個(gè)階段:1、建立連接 2、數(shù)據(jù)傳輸 3、斷開連接。

通常我們談到的超時(shí)分為兩種,connectTimeout 和socketTimeout,前者是網(wǎng)絡(luò)連接超時(shí),后者是執(zhí)行超時(shí)。

如果與數(shù)據(jù)庫(kù)服務(wù)器請(qǐng)求建立連接的時(shí)間超過ConnectionTimeOut,就會(huì)拋 ConnectionTimeOutException,即服務(wù)器連接超時(shí),沒有在規(guī)定的時(shí)間內(nèi)建立連接。如果服務(wù)器處理數(shù)據(jù)用時(shí)過長(zhǎng),超過了SocketTimeOut,就會(huì)拋SocketTimeOutExceptin,即服務(wù)器響應(yīng)超時(shí),服務(wù)器沒有在規(guī)定的時(shí)間內(nèi)返回給客戶端數(shù)據(jù)。(這里的異常是java驅(qū)動(dòng)返回的異常)

這兩個(gè)參數(shù),官方給出的是?connectTimeoutMS和socketTimeoutMS


生產(chǎn)環(huán)境下關(guān)于options參數(shù)

我們?cè)谏a(chǎn)環(huán)境下,參數(shù)replicaSet,connectTimeoutMS,socketTimeoutMS都沒有配置。

官方文檔

https://docs.mongodb.com/manual/replication/

https://docs.mongodb.com/manual/core/replica-set-members/

https://docs.mongodb.com/manual/reference/connection-string/


文章中的觀點(diǎn)有不嚴(yán)謹(jǐn)之處,歡迎評(píng)論溝通,關(guān)于副本集,筆者也是在不斷探索中。

抱著不確定性思維,學(xué)習(xí)MongoDb數(shù)據(jù)庫(kù)的基本態(tài)度:邊學(xué)習(xí),邊實(shí)踐,邊參考,邊改進(jìn),在問題中成長(zhǎng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容