MongoDB 維護Replica Set

在每一個MongoDB(版本 3.2.9) Instance中,都有一個本地數據庫(local),用於存儲 Replication 進程的信息和本地數據。local 數據庫的特性是:位於local數據庫中的數據和集合不會被 Replication 進程複製到其餘MongoDB instance上。若是實例上有些collection 和 data不計劃被複制到其餘MongoDB Instance,能夠將這些collection 和 data 存儲在local 數據庫中。node

MongoDB shell提供一個全局變量rs,是數據庫命令的包裝器(wrapper),用於維護Replica Set。mongodb

一,Replica Set的配置shell

1,查看Replica Set的配置信息數據庫

MongoDB 將Replica Set的配置信息存儲在local.system.replset 集合中,在同一個Replica Set中全部成員local.system.replset是相同的,不能直接修改該集合,必須經過rs.initiate()來初始化,經過 rs.reconfig()來從新配置,對Replica Set 增長或刪除成員都會相應的修改Replica Set的配置信息。數組

rs.config()

use local
db.system.replset.find()

配置信息重要信息主要有兩部分:Replica Set的 id 值 和 member 數組。app

{
_id: "replica set name",
members: [
    {
      _id: <int>,
      host: "host:port",
      arbiterOnly: <boolean>,
      buildIndexes: <boolean>,
      hidden: <boolean>,
      priority: <number>,
      slaveDelay: <int>,
      votes: <number>
    },
    ...
  ],
...
}

成員的配置文檔:async

priority:表示一個成員被選舉爲Primary節點的優先級,默認值是1,取值範圍是從0到100,將priority設置爲0有特殊含義:Priority爲0的成員永遠不能成爲Primary 節點。Replica Set中,Priority最高的成員,會優先被選舉爲Primary 節點,只要其知足條件。函數

hidden:將成員配置爲隱藏成員,要求Priority 爲0。Client不會向隱藏成員發送請求,所以隱藏成員不會收到Client的Request。ui

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.this

votes:有效值是0或1,默認值是1,若是votes是1,表示該成員(voting member)有權限選舉Primary 成員。在一個Replica Set中,最多有7個成員,其votes 屬性的值是1。

arbiterOnly:表示該成員是仲裁者,arbiter的惟一做用是就是參與選舉,其votes屬性是1,arbiter不保存數據,也不會爲client提供服務。

buildIndexes:表示實在在成員上建立Index,該屬性不能修改,只能在增長成員時設置該屬性。若是一個成員僅僅做爲備份,不接收Client的請求,將該成員設置爲不建立index,可以提升數據同步的效率。

2,從新配置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)

3,增長成員

3.1,該使用默認的配置增長成員

--增長一個成員,用於存儲數據
rs.add("host:port")

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

3.2,使用配置文檔增長成員

示例,爲Replica Set增長一個延遲備份的隱藏節點,滯後Primary節點1hour,該節點不參與投票,也不建立index,僅僅做爲數據備份。

rs.add( { _id:4, host: "host:port", priority: 0, hidden:true, slaveDelay:3600, votes:0, buildIndexes:true, arbiterOnly:false } )

4,刪除成員

rs.remove("host")

5,對replica set從新配置,可以增長成員,刪除成員,並能同時修改爲員的屬性

二,對Replica Set的成員進行操做

1,凍結當前成員,使當前成員在指定的時間內沒有資格成爲Primary,即當前成員在必定時間內保持Secondary身份

Makes the current replica set member ineligible to become primary for the period specified.

rs.freeze(seconds)

2,強制 Primary 節點退化爲Secondary節點

rs.stepDown()使當前Primary節點退化爲Secondary 節點,並激發選舉Primary的事件。該函數使當前的Primary 節點在指定的時間內,不能成爲Primary節點。在必定的時間內,若是有 Secondary 節點知足條件,那麼該Secondary節點被選舉爲Primary 節點;若是沒有 Secondary 節點知足條件,那麼原Primary節點參與選舉。stepDown函數,使Primary節點退化爲Secondary,並在一段時間內不能參與選舉。

Forces the primary of the replica set to become a secondary, triggering an election for primary. The method steps down the primary for a specified number of seconds; during this period, the stepdown member is ineligible from becoming primary.

rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)

3,強制當前成員從指定成員同步數據

rs.syncFrom("host:port");

4,使當前的Secondary 節點可以讀取數據

默認狀況下,Secondary 節點是不能讀取數據的

rs.slaveOk()

三,查看Replica Set的狀態

set字段:Replica Set的name

stateStr:成員狀態的描述信息

name:該成員的host 和 端口

syncTo:該成員從哪一個成員同步數據,可使用rs.syncFrom()強制同步的Path,從指定的 Target 成員同步數據。

{
    "set" : "rs0",
    "myState" : 1,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [ 
        {
            "_id" : 0,
            "name" : "cia-sh-05:40004",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 240973,
            "optime" : {
                "ts" : Timestamp(1473336939, 1),
                "t" : NumberLong(5)
            },
            "optimeDate" : ISODate("2016-09-08T12:15:39.000Z"),
            "lastHeartbeat" : ISODate("2016-09-10T04:39:55.041Z"),
            "lastHeartbeatRecv" : ISODate("2016-09-10T04:39:56.356Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "cia-sh-06:40001"
        }, .....
    ]
}

三,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。

3,修改oplog的大小

修改的過程主要分爲三步:

  • 以單機模式重啓mongod
  • 啓動以後,從新建立oplog,並保留最後一個記錄做爲種子
  • 以複製集方式重啓mongod

詳細過程是:

step1:以單機模式重啓mongod

對於Primary成員,首先調用stepDown函數,強制Primary成員轉變爲Secondary成員

rs.stepDown()

對於secondary成員,調用shutdownServer()函數,關閉mongod

use admin 
db.shutdownServer()

啓動mongod實例,不要使用replset參數

mongod --port 37017 --dbpath /srv/mongodb

step2:建立新的oplog

有備無患,備份oplog文件

mongodump --db local --collection 'oplog.rs' --port 37017

將oplog中最後一條有效記錄保存到temp 集合中,做爲新oplog的seed

use local

db.temp.drop()
db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )

db.oplog.rs.drop()

重建新的oplog集合,並將temp集合中一條記錄保存到oplog中,size的單位是Byte

db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } )
db.oplog.rs.save( db.temp.findOne() )

step3:以複製集模式啓動 mongod,replset參數必須制定正確的Replica Set的名字

db.shutdownServer()
mongod --replSet rs0 --dbpath /srv/mongodb

三,查看mongod 的開機日誌

在local.startup_log 集合中,存儲mongod 每次啓動時的開機日誌

 

參考文檔:

The local Database

Replica Set Configuration

Replica Set Oplog

Change the Size of the Oplog

相關文章
相關標籤/搜索