1. 程式人生 > >Mongodb3.4.2 Replica Set主節點及備份節點裁判節點

Mongodb3.4.2 Replica Set主節點及備份節點裁判節點

在每個MongoDB(版本 3.4.2) Instance中,都有一個本地資料庫(local),用於儲存 Replication 程序的資訊和本地資料。local 資料庫的特性是:位於local資料庫中的資料和集合不會被 Replication 程序複製到其他MongoDB instance上。如果例項上有些collection 和 data不計劃被複制到其他MongoDB Instance,可以將這些collection 和 data 儲存在local 資料庫中。

成員的配置文件:

priority:表示一個成員被選舉為Primary節點的優先順序,預設值是1,取值範圍是從0到100,將priority設定為0有特殊含義:Priority為0的成員永遠不能成為Primary 節點。Replica Set中,Priority最高的成員,會優先被選舉為Primary 節點,只要其滿足條件。


hidden:將成員配置為隱藏成員,要求Priority 為0。Client不會向隱藏成員傳送請求,因此隱藏成員不會收到Client的Request。


slaveDelay:單位是秒,將Secondary 成員配置為延遲備份節點,要求Priority 為0,表示該成員比Primary 成員滯後指定的時間,才能將Primary上進行的寫操作同步到本地。為了資料讀取的一致性,應將延遲備份節點的hidden設定為true,避免使用者讀取到明顯滯後的資料。Delayed members maintain a copy of the data that reflects the state of the data at some time in the past.


votes:有效值是0或1,預設值是1,如果votes是1,表示該成員(voting member)有許可權選舉Primary 成員。在一個Replica Set中,最多有7個成員,其votes 屬性的值是1。


arbiterOnly:表示該成員是仲裁者,arbiter的唯一作用是就是參與選舉,其votes屬性是1,arbiter不儲存資料,也不會為client提供服務。


buildIndexes:表示實在在成員上建立Index,該屬性不能修改,只能在增加成員時設定該屬性。如果一個成員僅僅作為備份,不接收Client的請求,將該成員設定為不建立index,能夠提高資料同步的效率。

1.建立三個節點目錄如下圖:

節點一:

節點二:

節點三:

2.對上面的三個節點分別在cfg檔案下新增配置檔案

節點一配置檔案:

logpath=D:\data1\logs\mongod.log
dbpath=D:\data1\db
logappend=true
#auth=true
port=27018
replSet=rs0

節點二配置檔案:

logpath=D:\data2\logs\mongod.log
dbpath=D:\data2\db
logappend=true
#auth=true
port=27019
replSet=rs0

節點三配置檔案:

logpath=D:\data3\logs\mongod.log
dbpath=D:\data3\db
logappend=true
#auth=true
port=27020
replSet=rs0

3.在每個節點下面配置配置啟動mongo資料庫例項start1.bat、start2.bat、start3.bat

節點一:mongod --config D:\data1\cfg\mongod.cfg----start1.bat

節點二:mongod --config D:\data2\cfg\mongod.cfg----start2.bat

節點三:mongod --config D:\data3\cfg\mongod.cfg----start3.bat

4.啟動上面的三個bat檔案

5.連線上節點一併執行如下命令:

 var config_rs = {_id : "rs0",members : [ { _id:0, host:"127.0.0.1:27018", priority:1 },{ _id:1, host:"127.0.0.1:27019", priority:1 },{ _id:2, host:"127.0.0.1:27020", priority:1, "arbiterOnly": true } ]}
 
 rs.initiate(config_rs)

輸入rs.status結果如下:

/* 1 */
{
    "set" : "rs0",
    "date" : ISODate("2017-06-26T08:48:15.107Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1498466889, 1),
            "t" : NumberLong(1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1498466889, 1),
            "t" : NumberLong(1)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1498466889, 1),
            "t" : NumberLong(1)
        }
    },
    "members" : [ 
        {
            "_id" : 0,
            "name" : "127.0.0.1:27018",
            "health" : 1.0,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 125,
            "optime" : {
                "ts" : Timestamp(1498466889, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-06-26T08:48:09.000Z"),
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1498466808, 1),
            "electionDate" : ISODate("2017-06-26T08:46:48.000Z"),
            "configVersion" : 1,
            "self" : true
        }, 
        {
            "_id" : 1,
            "name" : "127.0.0.1:27019",
            "health" : 1.0,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 98,
            "optime" : {
                "ts" : Timestamp(1498466889, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1498466889, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-06-26T08:48:09.000Z"),
            "optimeDurableDate" : ISODate("2017-06-26T08:48:09.000Z"),
            "lastHeartbeat" : ISODate("2017-06-26T08:48:14.262Z"),
            "lastHeartbeatRecv" : ISODate("2017-06-26T08:48:14.660Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "127.0.0.1:27018",
            "configVersion" : 1
        }, 
        {
            "_id" : 2,
            "name" : "127.0.0.1:27020",
            "health" : 1.0,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 98,
            "lastHeartbeat" : ISODate("2017-06-26T08:48:14.263Z"),
            "lastHeartbeatRecv" : ISODate("2017-06-26T08:48:13.559Z"),
            "pingMs" : NumberLong(0),
            "configVersion" : 1
        }
    ],
    "ok" : 1.0
}

通過結果可以看到主節點和副節點及裁判節點,主節點接受所有的讀寫操作,在主節點的所有更改都會同步奧副節點上去。

MongoDB shell提供一個全域性變數rs,是資料庫命令的包裝器(wrapper),用於維護Replica Set。

MongoDB 將Replica Set的配置資訊儲存在local.system.replset 集合中,在同一個Replica Set中所有成員local.system.replset是相同的,不能直接修改該集合,必須通過rs.initiate()來初始化,通過 rs.reconfig()來重新配置,對Replica Set 增加或刪除成員都會相應的修改Replica Set的配置資訊。

重新配置Replica Set


對Replica Set重新配置,必須連線到Primary 節點;如果Replica Set中沒有一個節點被選舉為Primary,那麼,可以使用force option(rs.reconfig(config,{force:true})),在Secondary 節點上強制對Replica Set進行重新配置。


The force parameter allows a reconfiguration command to be issued to a non-primary node. If set as { force: true }, this forces the replica set to accept the new configuration even if a majority of the members are not accessible. Use with caution, as this can lead to rollback situations.


示例,在primary 節點中,重新配置成員的優先順序屬性(priority)。


cfg = rs.conf()
cfg.members[0].priority = 1
cfg.members[1].priority = 1
cfg.members[2].priority = 5
rs.reconfig(cfg)

--增加一個成員,用於儲存資料
rs.add("host:port")

--增加一個arbiter,用於選舉
rs.add("host:port",true)

--刪除一個成員
rs.remove("host")

Replica Set的操作日誌

MongoDB的Replication實際上是基於操作日誌(operation log)的複製。Replication程序的整個過程是:Replication 將Primary節點中執行的寫操作記錄到oplog集合中,Secondary成員讀取Primary 成員的oplog集合,重做(redo)oplog中記錄的寫操作,最終,Replica Set中的各個成員達到資料的一致性。

oplog集合中記錄的操作是基於單個doc的,也就是說,如果一條命令隻影響一個doc,那麼Replication向oplog集合中插入一個操作命令;如果一個命令影響多個doc,那麼Replication將該命令拆分成多個等效的操作命令,每個操作命令只會影響一個doc,最終向oplog集合中插入的是多個操作命令。

1,oplog 集合

oplog集合是一個特殊的固定集合,儲存的是Primary節點的操作日誌,每個Replica Set的成員都一個oplog的副本:local.oplog.rs,該集合儲存在每個成員的local資料庫中。Replica Set中的每個成員都有一個oplog集合,用於儲存當前節點的操作記錄,其他成員能夠從任何一個成員的oplog中同步資料。

The oplog (operations log) is a special capped collection that keeps a rolling record of all operations that modify the data stored in your databases. MongoDB applies database operations on the primary and then records the operations on the primary’s oplog. The secondary members then copy and apply these operations in an asynchronous process. All replica set members contain a copy of the oplog, in the local.oplog.rs collection, which allows them to maintain the current state of the database.

2,oplog的大小

oplog集合是一個固定集合,其大小是固定的,在第一次開始Replica Set的成員時,MongoDB建立預設大小的oplog。在MongoDB 3.2.9 版本中,MongoDB 預設的儲存引擎是WiredTiger,一般情況下,oplog的預設大小是資料檔案所在disk 空閒空間(disk free space)的5%,最小不會低於990 MB,最大不會超過50 GB。