MongoDB日常運維-04副本集搭建

chenoracle發表於2020-03-22

MongoDB日常運維-04副本集搭建 

一:MongoDB常用命令彙總

二:MongoDB安裝

三:MongoDB主從複製搭建

四:MongoDB副本集搭建 

五:MongoDB副本集故障切換

六:MongoDB副本集搭建錯誤彙總


參考:

https://blog.csdn.net/qq_39329616/article/details/89409728

四:MongoDB副本集搭建 

為了解決主從複製的故障自動轉移問題。

沒有固定的主節點,叢集會自動選舉出一個主節點,當這個主節點不能正常工作時,又會另外選舉出其他節點作為主節點。

副本集中總會有一個主節點和一個(多個)備份節點,當主節點出問題時,備份節點會提升為主節點。

在副本集中會有一個只參與投票選舉、不復制資料的仲裁節點,用於當票數出現一致時來判決。官方推薦叢集節點為奇數。

副本集工作原理

1.oplog(操作日誌)

記錄資料改變操作(更新插入),oplog是一個固定集合,位於每個複製節點的local的資料庫裡。

新操作會替換舊的操作,以保證oplog不會超過預設的大小,oplog中的每個文件都代表主節點上執行的一個操作。

2.資料同步

每個oplog都有時間戳,所有從節點都使用這個時間戳來追蹤它們最後執行寫操作的記錄。

當某個從節點準備更新自己時,會做三件事:

首先,檢視自己oplog裡的最後一條時間戳;

其次,查詢主節點oplog裡所有大於此時間戳的文件;

最後,把那些文件應用到自己庫裡,並新增寫操作文件到自己的oplog裡。

3.複製狀態和本地資料庫

複製狀態的文件記錄在本地資料庫local中。

主節點的local資料庫的內容是不會被從節點複製的。

如果有不想被從節點複製的文件,可以將它放在本地資料庫local中。

4.阻塞複製

當主節點寫入操作太快時,從節點的更新狀態有可能跟不上。

為避免這種情況:

使主節點的oplog足夠大

阻塞複製:在主節點使用getLastError命令加引數“w”來確保資料的同步性。w越大會導致寫操作越慢。

5.心跳機制

心跳檢測有助於發現故障進行自動選舉和故障轉移。預設情況下副本整合員每兩分鐘ping一下其他成員,來檢測健康狀態。

如果是某一從節點出現故障只會等待從節點重新上線,而如果主節點出現故障,則副本集開始選舉,重新選出新的主節點,原主節點會降級為從節點。

6.選舉機制

根據優先順序和Bully演算法(評判誰的資料最新)選舉出主節點,在選舉出主節點之前,整個叢集服務是隻讀的,不能執行寫操作。

非仲裁節點都會有優先順序配置,範圍為0~100,越大值越優先成為主節點,預設為1,如果是0則不能成為主節點。

擁有資格的從節點會向其他節點發出請求,而其他節點在收到選舉提議後會判斷三個條件:

1 副本集中是否有其他節點已經是主節點了

2 自己的資料是否比請求成為主節點的的那個節點上資料更新

3 副本集中其他節點的資料是否比請求成為主節點的那個節點資料更新

只要有一個條件成立,都會認為對方提議不可行。請求者只要收到任何一個節點返回不合適,都會退出選舉。

選舉機制會讓優先順序高的節點成為主節點,即使先選舉出了優先順序低的節點,也至少會短暫作為主節點執行一段時間。

副本集還會再之後繼續發出選舉,直到優先順序最高的節點成為主節點。

7.資料回滾

在從節點成為主節點後,會認為其是副本集中的最新資料,對其他節點的操作都會回滾,即所有節點連線新的主節點重新同步。

這些節點會檢視自己的oplog,找出新主節點中沒有執行過的操作,然後請求操作文件,替換掉自己的異常樣本。

副本集搭建

主庫:192.168.2.222 cjcos 

從庫:192.168.2.187 rac1  

仲裁:192.168.2.188 rac2 

1 三個節點新增配置檔案

[root@cjcos conf]# pwd

/usr/local/mongodb/conf

[root@cjcos conf]# vim mongodb.conf

#叢集名稱

replSet=cjcmonset

2 啟動資料庫 

[root@cjcos conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf 

[root@rac1 conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf 

[root@rac2 conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf 

3 配置副本集

3.1 配置主primary

> use admin

switched to db admin

> config={_id:"cjcmonset",members:

[{_id:0,host:"192.168.2.222:27017",priority:1},

{_id:1,host:"192.168.2.187:27017",priority:1},

{_id:2,host:"192.168.2.188:27017",priority:1,arbiterOnly:true}]}

{

"_id" : "cjcmonset",

"members" : [

{

"_id" : 0,

"host" : "192.168.2.222:27017",

"priority" : 1

},

{

"_id" : 1,

"host" : "192.168.2.187:27017",

"priority" : 1

},

{

"_id" : 2,

"host" : "192.168.2.188:27017",

"priority" : 1,

"arbiterOnly" : true

}

]

}

初始化配置

> rs.initiate(config)

{

"ok" : 1,

"$clusterTime" : {

"clusterTime" : Timestamp(1584862345, 1),

"signature" : {

"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),

"keyId" : NumberLong(0)

}

},

"operationTime" : Timestamp(1584862345, 1)

}

檢視叢集配置

cjcmonset:PRIMARY> rs.config()

{

"_id" : "cjcmonset",

"version" : 1,

"protocolVersion" : NumberLong(1),

"writeConcernMajorityJournalDefault" : true,

"members" : [

{

"_id" : 0,

"host" : "192.168.2.222:27017",

"arbiterOnly" : false,

"buildIndexes" : true,

"hidden" : false,

"priority" : 1,

"tags" : {

},

"slaveDelay" : NumberLong(0),

"votes" : 1

},

{

"_id" : 1,

"host" : "192.168.2.187:27017",

"arbiterOnly" : false,

"buildIndexes" : true,

"hidden" : false,

"priority" : 1,

"tags" : {

},

"slaveDelay" : NumberLong(0),

"votes" : 1

},

{

"_id" : 2,

"host" : "192.168.2.188:27017",

"arbiterOnly" : true,

"buildIndexes" : true,

"hidden" : false,

"priority" : 0,

"tags" : {

},

"slaveDelay" : NumberLong(0),

"votes" : 1

}

],

"settings" : {

"chainingAllowed" : true,

"heartbeatIntervalMillis" : 2000,

"heartbeatTimeoutSecs" : 10,

"electionTimeoutMillis" : 10000,

"catchUpTimeoutMillis" : -1,

"catchUpTakeoverDelayMillis" : 30000,

"getLastErrorModes" : {

},

"getLastErrorDefaults" : {

"w" : 1,

"wtimeout" : 0

},

"replicaSetId" : ObjectId("5e77148837ae69b4ab9b4870")

}

}

檢視狀態:

cjcmonset:PRIMARY> rs.status()

{

"set" : "cjcmonset",

"date" : ISODate("2020-03-22T07:34:18.866Z"),

"myState" : 1,

"term" : NumberLong(1),

"syncingTo" : "",

"syncSourceHost" : "",

"syncSourceId" : -1,

"heartbeatIntervalMillis" : NumberLong(2000),

"majorityVoteCount" : 2,

"writeMajorityCount" : 2,

"optimes" : {

"lastCommittedOpTime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"lastCommittedWallTime" : ISODate("2020-03-22T07:34:16.862Z"),

"readConcernMajorityOpTime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"readConcernMajorityWallTime" : ISODate("2020-03-22T07:34:16.862Z"),

"appliedOpTime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"durableOpTime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"lastAppliedWallTime" : ISODate("2020-03-22T07:34:16.862Z"),

"lastDurableWallTime" : ISODate("2020-03-22T07:34:16.862Z")

},

"lastStableRecoveryTimestamp" : Timestamp(1584862416, 1),

"lastStableCheckpointTimestamp" : Timestamp(1584862416, 1),

"electionCandidateMetrics" : {

"lastElectionReason" : "electionTimeout",

"lastElectionDate" : ISODate("2020-03-22T07:32:35.618Z"),

"electionTerm" : NumberLong(1),

"lastCommittedOpTimeAtElection" : {

"ts" : Timestamp(0, 0),

"t" : NumberLong(-1)

},

"lastSeenOpTimeAtElection" : {

"ts" : Timestamp(1584862345, 1),

"t" : NumberLong(-1)

},

"numVotesNeeded" : 2,

"priorityAtElection" : 1,

"electionTimeoutMillis" : NumberLong(10000),

"numCatchUpOps" : NumberLong(0),

"newTermStartDate" : ISODate("2020-03-22T07:32:36.851Z"),

"wMajorityWriteAvailabilityDate" : ISODate("2020-03-22T07:32:37.889Z")

},

"members" : [

{

"_id" : 0,

"name" : "192.168.2.222:27017",

"health" : 1,

"state" : 1,

"stateStr" : "PRIMARY",

"uptime" : 211,

"optime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"optimeDate" : ISODate("2020-03-22T07:34:16Z"),

"syncingTo" : "",

"syncSourceHost" : "",

"syncSourceId" : -1,

"infoMessage" : "could not find member to sync from",

"electionTime" : Timestamp(1584862355, 1),

"electionDate" : ISODate("2020-03-22T07:32:35Z"),

"configVersion" : 1,

"self" : true,

"lastHeartbeatMessage" : ""

},

{

"_id" : 1,

"name" : "192.168.2.187:27017",

"health" : 1,

"state" : 2,

"stateStr" : "SECONDARY",

"uptime" : 113,

"optime" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"optimeDurable" : {

"ts" : Timestamp(1584862456, 1),

"t" : NumberLong(1)

},

"optimeDate" : ISODate("2020-03-22T07:34:16Z"),

"optimeDurableDate" : ISODate("2020-03-22T07:34:16Z"),

"lastHeartbeat" : ISODate("2020-03-22T07:34:17.751Z"),

"lastHeartbeatRecv" : ISODate("2020-03-22T07:34:18.157Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "",

"syncingTo" : "192.168.2.222:27017",

"syncSourceHost" : "192.168.2.222:27017",

"syncSourceId" : 0,

"infoMessage" : "",

"configVersion" : 1

},

{

"_id" : 2,

"name" : "192.168.2.188:27017",

"health" : 1,

"state" : 7,

"stateStr" : "ARBITER",

"uptime" : 113,

"lastHeartbeat" : ISODate("2020-03-22T07:34:17.750Z"),

"lastHeartbeatRecv" : ISODate("2020-03-22T07:34:17.948Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "",

"syncingTo" : "",

"syncSourceHost" : "",

"syncSourceId" : -1,

"infoMessage" : "",

"configVersion" : 1

}

],

"ok" : 1,

"$clusterTime" : {

"clusterTime" : Timestamp(1584862456, 1),

"signature" : {

"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),

"keyId" : NumberLong(0)

}

},

"operationTime" : Timestamp(1584862456, 1)

}

資料同步測試

主庫建立測試資料庫cjcdb,建立測試表t01並插入資料 

cjcmonset:PRIMARY> use cjcdb

switched to db cjcdb

cjcmonset:PRIMARY> show collections

cjcmonset:PRIMARY> db.createCollection("t01")

{

"ok" : 1,

"$clusterTime" : {

"clusterTime" : Timestamp(1584880911, 1),

"signature" : {

"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),

"keyId" : NumberLong(0)

}

},

"operationTime" : Timestamp(1584880911, 1)

}

cjcmonset:PRIMARY> db.t01.insert({"tname":"cjc"})

WriteResult({ "nInserted" : 1 })

cjcmonset:PRIMARY> db.t01.find()

{ "_id" : ObjectId("5e775d3d1cf1e6a03a41253c"), "tname" : "cjc" }

檢視資料庫

cjcmonset:PRIMARY> show dbs

admin   0.000GB

cjcdb   0.000GB

config  0.000GB

local   0.000GB

從庫檢視資料

187從庫:

cjcmonset:SECONDARY> show dbs

2020-03-22T20:43:47.784+0800 E  QUERY    [js] uncaught exception: Error: listDatabases failed:{

"operationTime" : Timestamp(1584881019, 1),

"ok" : 0,

"errmsg" : "not master and slaveOk=false",

"code" : 13435,

"codeName" : " NotMasterNoSlaveOk",

"$clusterTime" : {

"clusterTime" : Timestamp(1584881019, 1),

"signature" : {

"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),

"keyId" : NumberLong(0)

}

}

} :

_getErrorWithCode@src/mongo/shell/utils.js:25:13

Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:135:19

Mongo.prototype.getDBs@src/mongo/shell/mongo.js:87:12

shellHelper.show@src/mongo/shell/utils.js:906:13

shellHelper@src/mongo/shell/utils.js:790:15

@(shellhelp2):1:1

cjcmonset:SECONDARY> rs.slaveOk()

cjcmonset:SECONDARY> show dbs

admin   0.000GB

cjcdb   0.000GB

config  0.000GB

local   0.000GB

cjcmonset:SECONDARY> use cjcdb

switched to db cjcdb

cjcmonset:SECONDARY> db.t01.find()

{ "_id" : ObjectId("5e775d3d1cf1e6a03a41253c"), "tname" : "cjc" }

主庫日誌如下:

2020-03-22T20:41:51.247+0800 I  STORAGE  [conn1] createCollection: cjcdb.t01 with generated UUID: 7dd8d050-ac8b-4c6d-b46d-43a8c54b74a2 and options: {}

2020-03-22T20:41:51.541+0800 I  INDEX    [conn1] index build: done building index _id_ on ns cjcdb.t01

2020-03-22T20:41:51.542+0800 I  COMMAND  [conn1] command cjcdb.t01 appName: "MongoDB Shell" command: create { create: "t01", lsid: { id: UUID("3383ae30-677c-4fce-b244-162342b1a28e") }, $clusterTime: { clusterTime: Timestamp(1584880879, 1), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } }, $db: "cjcdb" } numYields:0 reslen:163 locks:{ ParallelBatchWriterMode: { acquireCount: { r: 2 } }, ReplicationStateTransition: { acquireCount: { w: 2 } }, Global: { acquireCount: { w: 2 } }, Database: { acquireCount: { w: 1, W: 1 } }, Collection: { acquireCount: { r: 2, W: 1 } }, Mutex: { acquireCount: { r: 1 } } } flowControl:{ acquireCount: 2 } storage:{} protocol:op_msg 294ms

2020-03-22T20:42:37.293+0800 I  SHARDING [conn1] Marking collection cjcdb.t01 as collection version: <unsharded>

188仲裁節點

而進入仲裁者節點時,會發現不能讀寫,因為他只負責投票選舉。

cjcmonset:ARBITER> rs.slaveOk()

cjcmonset:ARBITER> show dbs

local  0.000GB

歡迎關注我的微信公眾號"IT小Chen",共同學習,共同成長!!!  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29785807/viewspace-2681965/,如需轉載,請註明出處,否則將追究法律責任。

相關文章