MongoDB高可用
對(duì)于MongoDB,可以支持使用單機(jī)模式提供服務(wù),但是在實(shí)際的生產(chǎn)環(huán)境中,單機(jī)模式將面臨很大的風(fēng)險(xiǎn),一旦這個(gè)數(shù)據(jù)庫(kù)服務(wù)出現(xiàn)問(wèn)題,就會(huì)導(dǎo)致線上的服務(wù)出現(xiàn)錯(cuò)誤甚至崩潰。因此,在實(shí)際生產(chǎn)環(huán)境下,需要對(duì)MongoDB做相應(yīng)的主備處理,提高數(shù)據(jù)庫(kù)服務(wù)的可用性。
對(duì)于提高可用性,一些博文里提到了使用主從模式(master-slaver)。
WARNING:
Deprecated since version 3.2: MongoDB 3.2 deprecates the use of master-slave replication for components of sharded clusters.
主從模式是高可用的一種方案。然而從上面這段警告中可以知道,在高版本的MongoDB(3.2以上)中,官方已經(jīng)不推薦使用主從模式,取而代之的,是使用復(fù)制集(Replica Set)的方式做主備處理。
IMPORTANT:
Replica sets replace master-slave replication for most use cases. If possible, use replica sets rather than master-slave replication for all new production deployments. This documentation remains to support legacy deployments and for archival purposes only.
一、主從復(fù)制
對(duì)于主從復(fù)制的原理,非常簡(jiǎn)單,簡(jiǎn)單的說(shuō)就是幾臺(tái)機(jī)器之間進(jìn)行同步操作,我們?cè)谥鞴?jié)點(diǎn)上操作數(shù)據(jù),需要同步到其他子節(jié)點(diǎn)上。下面我們來(lái)實(shí)戰(zhàn)一下。
首先創(chuàng)建一個(gè)cluster文件夾,然后在該文件夾中創(chuàng)建兩個(gè)子文件夾master和slave分別存放主從節(jié)點(diǎn)的數(shù)據(jù)文件。
二、副本集
副本集具有自動(dòng)故障恢復(fù)的功能。
主從集群和副本集最大的區(qū)別就是副本集沒有固定的“主節(jié)點(diǎn)”;整個(gè)集群會(huì)選出一個(gè)“主節(jié)點(diǎn)”,當(dāng)其掛掉后,又在剩下的從節(jié)點(diǎn)中選中其他節(jié)點(diǎn)為“主節(jié)點(diǎn)”,副本集總有一個(gè)活躍點(diǎn)(primary)和一個(gè)或多個(gè)備份節(jié)點(diǎn)(secondary)。
在復(fù)制集中,有且只有一個(gè)主節(jié)點(diǎn)(primary),可以包含一個(gè)或多個(gè)從節(jié)點(diǎn)(secondary),主從節(jié)點(diǎn)直接會(huì)通過(guò)心跳檢測(cè)來(lái)確定節(jié)點(diǎn)是否健康或存活。所有的讀寫操作都是在主節(jié)點(diǎn)上進(jìn)行的,如果要實(shí)現(xiàn)讀寫分離,需要進(jìn)行相應(yīng)的處理,這個(gè)最后會(huì)說(shuō)。從節(jié)點(diǎn)會(huì)根據(jù)oplog(也就是操作日志)來(lái)復(fù)制主節(jié)點(diǎn)的數(shù)據(jù)。

MongoDB復(fù)制集
除了主從節(jié)點(diǎn)外,MongoDB的復(fù)制集中還存在著一種叫仲裁者(Arbiter)的角色。一個(gè)仲裁者節(jié)點(diǎn)是比較輕量級(jí)的,因?yàn)樗粫?huì)去復(fù)制主庫(kù)的數(shù)據(jù),因此也就不會(huì)成為主節(jié)點(diǎn);但是,它的作用是在投票選舉階段——當(dāng)主節(jié)點(diǎn)故障時(shí),仲裁者可以進(jìn)行投票。一般來(lái)說(shuō),不建議一個(gè)復(fù)制集中包含超過(guò)一個(gè)仲裁者。
當(dāng)主節(jié)點(diǎn)突然故障后,MongoDB有自己的機(jī)制,會(huì)自動(dòng)切換,通過(guò)選舉,在從節(jié)點(diǎn)中選出一個(gè)節(jié)點(diǎn)作為新的主節(jié)點(diǎn)。

三、分片
分片(sharding)是指將數(shù)據(jù)拆分,將其分散存在不同的機(jī)器上的過(guò)程。有時(shí)也用分區(qū)(partitioning)來(lái)表示這個(gè)概念。將數(shù)據(jù)分散到不同的機(jī)器上,不需要功能強(qiáng)大的大型計(jì)算機(jī)就可以儲(chǔ)存更多的數(shù)據(jù),處理更多的負(fù)載。
MongoDB分片的基本思想就是將集合切分成小塊。這些塊分散到若干片里面,每個(gè)片只負(fù)責(zé)總數(shù)據(jù)的一部分。應(yīng)用程序不必知道哪片對(duì)應(yīng)哪些數(shù)據(jù),甚至不需要知道數(shù)據(jù)已經(jīng)被拆分了,所以在分片之前要運(yùn)行一個(gè)路由進(jìn)程,該進(jìn)程名為mongos。這個(gè)路由器知道所有數(shù)據(jù)的存放位置,所以應(yīng)用可以連接它來(lái)正常發(fā)送請(qǐng)求。對(duì)應(yīng)用來(lái)說(shuō),它僅知道連接了一個(gè)普通的mongod。路由器知道數(shù)據(jù)和片的對(duì)應(yīng)關(guān)系,能夠轉(zhuǎn)發(fā)請(qǐng)求道正確的片上。如果請(qǐng)求有了回應(yīng),路由器將其收集起來(lái)回送給應(yīng)用。
設(shè)置分片時(shí),需要從集合里面選一個(gè)鍵,用該鍵的值作為數(shù)據(jù)拆分的依據(jù)。這個(gè)鍵稱為片鍵(shard key)。
用個(gè)例子來(lái)說(shuō)明這個(gè)過(guò)程:假設(shè)有個(gè)文檔集合表示的是people。如果選擇名字(“name”)作為片鍵,第一片可能會(huì)存放名字以A-F開頭的文檔,第二片存的G-P的名字,第三片存的Q~Z的名字。隨著添加或者刪除片,MongoDB會(huì)重新平衡數(shù)據(jù),使每片的流量都比較均衡,數(shù)據(jù)量也在合理范圍內(nèi)。
-
分片的架構(gòu)圖如下,這里用兩臺(tái)服務(wù)器來(lái)進(jìn)行分片操作:
image.png -
下圖展示了在MongoDB中使用分片集群結(jié)構(gòu)分布:
image.png

