MongoDB基礎(chǔ)可參考https://blog.51cto.com/kaliarch/2044423
10年積累的網(wǎng)站制作、成都做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有昌吉免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
一、概述
1.1 MongoDB副本集
通俗來講,mongodb的副本集相當(dāng)于具有自動故障恢復(fù)的主從集群,主從集群和副本集最明顯的特征為副本集沒有固定的“主節(jié)點”,整個集群會通過一定的算法選舉出主節(jié)點,目前MongoDB官方已經(jīng)不建議使用主從模式了,在主從模式下,如果主數(shù)據(jù)庫宕機,從數(shù)據(jù)庫無法自動接管主數(shù)據(jù)庫,從而無法接入數(shù)據(jù),取而代之的就是MongoDB副本集模式,主服務(wù)器負責(zé)整個副本集的讀寫,副本集定期同步數(shù)據(jù)備份,副本集中的副本節(jié)點在主節(jié)點掛掉后通過心跳機制檢測到后副本節(jié)點就會選舉一個新的主服務(wù)器,這一切對于應(yīng)用服務(wù)器無需關(guān)心。
1.2 架構(gòu)圖
1.3 復(fù)制原理
mongodb的復(fù)制至少需要兩個節(jié)點。其中一個是主節(jié)點,負責(zé)處理客戶端請求,其余的都是從節(jié)點,負責(zé)復(fù)制主節(jié)點上的數(shù)據(jù)。
mongodb各個節(jié)點常見的搭配方式為:一主一從、一主多從。
主節(jié)點記錄在其上的所有操作oplog,從節(jié)點定期輪詢主節(jié)點獲取這些操作,然后對自己的數(shù)據(jù)副本執(zhí)行這些操作,從而保證從節(jié)點的數(shù)據(jù)與主節(jié)點一致。
1.4 副本集特征:
N 個節(jié)點的集群
任何節(jié)點可作為主節(jié)點
所有寫入操作都在主節(jié)點上
自動故障轉(zhuǎn)移
自動恢復(fù)
1.5 Bully算法
如果副本集中主節(jié)點宕掉后,需要使用bully算法進行選舉主節(jié)點,其主要思想為每個成員均可以聲明自己為主節(jié)點并通知其他節(jié)點,別的節(jié)點可以選擇接受這個聲明或是拒絕并進入主節(jié)點競爭,只有被其他節(jié)點接受的節(jié)點才可以當(dāng)主節(jié)點,
節(jié)點按照一些屬性來判斷誰應(yīng)該勝出。這個屬性可以是一個靜態(tài)ID,也可以是更新的度量像最近一次事務(wù)ID(最新的節(jié)點會勝出)
官方描述:
得到每個服務(wù)器節(jié)點的最后操作時間戳。每個mongodb都有oplog機制會記錄本機的操作,方便和主服務(wù)器進行對比數(shù)據(jù)是否同步還可以用于錯誤恢復(fù)。
如果集群中大部分服務(wù)器down機了,保留活著的節(jié)點都為 secondary狀態(tài)并停止,不選舉了。
如果集群中選舉出來的主節(jié)點或者所有從節(jié)點最后一次同步時間看起來很舊了,停止選舉等待人來操作。
如果上面都沒有問題就選擇最后操作時間戳最新(保證數(shù)據(jù)是最新的)的服務(wù)器節(jié)點作為主節(jié)點。
1.6 Replica Set成員
一個Replica Set中的成員角色有三種:Primary,Secondary和Arbiter。
Primary:接收來自客戶端的所有的寫操作,一個Replica Set中有且只有一個Primary。Primary如果宕掉,Replica Set會自動選舉一個Secondary成為Primary。Primary將它data sets的所有操作都記錄到oplog中。
Secondary:Secondary從Primary復(fù)制oplog,然后將oplog中的操作應(yīng)用到自己的data sets。Secondary和Primary之間是異步復(fù)制,也就是Secondary中的數(shù)據(jù)可能不是最新的。默認情況下,Secondary不可讀不可寫,但是可以通過設(shè)置運行客戶端從Secondary讀。
Secondary配置的三種用途:
1.在選舉中阻止其成為Primary,只用作備份數(shù)據(jù)。通過設(shè)置優(yōu)先級priority為0來實現(xiàn)
2.阻止應(yīng)用程序從它讀,通過設(shè)置優(yōu)先級priority為0和設(shè)置hidden為true來實現(xiàn)。(一個隱藏的成員同樣復(fù)制Primary的數(shù)據(jù),但是對于客戶端應(yīng)用程序來講,它不可見。)
3.保留歷史鏡像數(shù)據(jù)用于數(shù)據(jù)回檔,比如如果誤刪除數(shù)據(jù),可以使用Delayed Replica Set成員中的數(shù)據(jù)恢復(fù)。
Arbiter:Arbiter不需要維護自己的data sets,只是當(dāng)Primary掛掉之后參與投票選擇哪個Secondary可以升級為Primary
Replica Set中的成員個數(shù)為偶數(shù)個時,就需要添加一個Arbiter用于投票選舉哪個可以升級為Primary,不能在Primary或者Secondary主機上運行Arbiter
一個Replica Set可以最多擁有12個成員,但是只有7個成員可以同時參與投票選舉成為Primary,如果成員數(shù)量超過12,就需要使用Master-Slave主從復(fù)制方式。
部署一個Replica Set至少需要三個成員,一個Arbiter,一個Secondary和一個Primary或者一個Primary,兩個Secondary。
二、搭建部署
2.1 基礎(chǔ)環(huán)境
主機名 | IP地址 | 系統(tǒng) |
mongodb-1 | 172.20.6.10 | CentOS release 6.9 |
mongodb-2 | 172.20.6.11 | CentOS release 6.9 |
mongodb-3 | 172.20.6.10 | CentOS release 6.9 |
2.2 軟件安裝
在三臺服務(wù)器上依次安裝mongodb
wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.10.tgz tar -zxvf mongodb-linux-x86_64-rhel62-3.4.10.tgz ln -sv mongodb-linux-x86_64-rhel62-3.4.10 mongodb mkdir /usr/local/mongodb/{conf,mongoData,mongoLog} touch /usr/local/mongodb/mongoLog/mongodb.log echo "export PATH=$PAHT:/usr/local/mongodb/bin">/etc/profile.d/mongodb.sh source etc/profile.d/mongodb.sh
定義配置文件
cat >/usr/local/mongodb/conf/mongodb.conf<依次啟動三個mongodb
mongodb -f /usr/local/mongodb/conf/mongodb.conf2.3 副本集部署
挑選任意一臺mongodb進行登錄
use admin #切換到admin數(shù)據(jù)庫 config = {_id:"RS",members:[ #定義副本集配置 {_id:0,host:"172.20.6.10:27017"}, {_id:1,host:"172.20.6.11:27017"}, {_id:2,host:"172.20.6.12:27017"},] } rs.initiate(config); #初始化副本集配置RS:PRIMARY> rs.status(); #查看副本集狀態(tài) { "set" : "RS", "date" : ISODate("2017-11-26T14:09:00.054Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "172.20.6.10:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #主節(jié)點 "uptime" : 377, "optime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-26T14:08:53Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1511705241, 1), "electionDate" : ISODate("2017-11-26T14:07:21Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "172.20.6.11:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #secondary節(jié)點 "uptime" : 109, "optime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-26T14:08:53Z"), "optimeDurableDate" : ISODate("2017-11-26T14:08:53Z"), "lastHeartbeat" : ISODate("2017-11-26T14:09:00.053Z"), "lastHeartbeatRecv" : ISODate("2017-11-26T14:08:59.072Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.10:27017", "configVersion" : 1 }, { "_id" : 2, "name" : "172.20.6.12:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #secondary節(jié)點 "uptime" : 109, "optime" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1511705333, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-26T14:08:53Z"), "optimeDurableDate" : ISODate("2017-11-26T14:08:53Z"), "lastHeartbeat" : ISODate("2017-11-26T14:09:00.053Z"), "lastHeartbeatRecv" : ISODate("2017-11-26T14:08:59.054Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.10:27017", "configVersion" : 1 } ], "ok" : 1 }此時replica set集群已結(jié)搭建成功
三、副本集測試
3.1 數(shù)據(jù)復(fù)制測試
在主節(jié)點創(chuàng)建數(shù)據(jù)庫,并創(chuàng)建集合,插入文檔,在secondary查看文檔
此時已經(jīng)完成在主節(jié)點創(chuàng)建數(shù)據(jù),接下來在secondary查看數(shù)據(jù)是否已經(jīng)同步過去。
mongodb默認是從主節(jié)點讀寫數(shù)據(jù)的,副本節(jié)點上不允許讀,需要設(shè)置副本節(jié)點可以讀。
db.getMongo().setSlaveOk(); #設(shè)置副本節(jié)點可讀此時我們可以測試得到數(shù)據(jù),數(shù)據(jù)已經(jīng)同步到secondary上,但是無法在secondary上進行數(shù)據(jù)的增刪改操作。
3.2 故障轉(zhuǎn)移測試
目前mongodb-1為主節(jié)點,mongdb-2、mongodb-3為副本集節(jié)點,此時停掉主節(jié)點的mongod服務(wù),進行故障轉(zhuǎn)移測試。
宕掉主節(jié)點mongodb-1的服務(wù)后,我們登錄mongodb-2,查看副本集狀態(tài):
RS:PRIMARY> rs.status() { "set" : "RS", "date" : ISODate("2017-11-26T14:35:03.422Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "172.20.6.10:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", #mongodb-1已經(jīng)失去連接 "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-11-26T14:35:02.502Z"), "lastHeartbeatRecv" : ISODate("2017-11-26T14:32:20.434Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "172.20.6.11:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #mongodb-2為新的主節(jié)點 "uptime" : 1842, "optime" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-26T14:35:01Z"), "electionTime" : Timestamp(1511706750, 1), "electionDate" : ISODate("2017-11-26T14:32:30Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "172.20.6.12:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #mongodb-3為secondary節(jié)點 "uptime" : 1671, "optime" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1511706901, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-26T14:35:01Z"), "optimeDurableDate" : ISODate("2017-11-26T14:35:01Z"), "lastHeartbeat" : ISODate("2017-11-26T14:35:02.354Z"), "lastHeartbeatRecv" : ISODate("2017-11-26T14:35:02.730Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.11:27017", "configVersion" : 1 } ], "ok" : 1 }查看mongodb-2的日志,發(fā)現(xiàn)mongodb-1心跳檢查已經(jīng)失去連接,重新進行了主節(jié)點選舉
此時在新節(jié)點mongodb-2進行文檔插入操作
此時上線mongodb-1,查看集群狀態(tài)與數(shù)據(jù)是否正常同步到mongodb-1上。
啟動mongodb-1的服務(wù),查看集群狀態(tài),此時mongodb-1已結(jié)成為新的secondary節(jié)點。
RS:PRIMARY> rs.status() { "set" : "RS", "date" : ISODate("2017-11-27T02:13:41.683Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "172.20.6.10:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #mongodb-1為secondary節(jié)點 "uptime" : 1945, "optime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-27T02:13:32Z"), "optimeDurableDate" : ISODate("2017-11-27T02:13:32Z"), "lastHeartbeat" : ISODate("2017-11-27T02:13:41.373Z"), "lastHeartbeatRecv" : ISODate("2017-11-27T02:13:40.854Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.12:27017", "configVersion" : 1 }, { "_id" : 1, "name" : "172.20.6.11:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #mongodb-2為主節(jié)點 "uptime" : 43760, "optime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-27T02:13:32Z"), "electionTime" : Timestamp(1511706750, 1), "electionDate" : ISODate("2017-11-26T14:32:30Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "172.20.6.12:27017", #mongodb-3為secondary節(jié)點 "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 43589, "optime" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1511748812, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-27T02:13:32Z"), "optimeDurableDate" : ISODate("2017-11-27T02:13:32Z"), "lastHeartbeat" : ISODate("2017-11-27T02:13:41.220Z"), "lastHeartbeatRecv" : ISODate("2017-11-27T02:13:41.209Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.11:27017", "configVersion" : 1 } ], "ok" : 1 }查看mongodb-1數(shù)據(jù)已經(jīng)正常同步。
四、其他
如果考慮到主服務(wù)器的復(fù)制壓力過大,可以制作仲裁節(jié)點,其中的仲裁節(jié)點不存儲數(shù)據(jù),只是負責(zé)故障轉(zhuǎn)移的群體投票,這樣就少了數(shù)據(jù)復(fù)制的壓力。
刪除節(jié)點:
rs.remove("172.20.6.12:27017") #刪除節(jié)點添加節(jié)點
rs.add("172.20.6.12:27017") #添加節(jié)點 rs.addArb("172.20.6.12:27017") #添加arbiter節(jié)點{ "_id" : 2, "name" : "172.20.6.12:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", #arbiter節(jié)點 "uptime" : 4, "lastHeartbeat" : ISODate("2017-11-27T02:35:01.634Z"), "lastHeartbeatRecv" : ISODate("2017-11-27T02:35:00.637Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.11:27017", "configVersion" : 9 }
當(dāng)前標(biāo)題:搭建高可用MongoDB集群(Replicaset)
文章網(wǎng)址:http://weahome.cn/article/ijsjep.html