MongoDB副本集(一主一備+仲裁)環境部署-運維操做記錄

 

MongoDB複製集是一個帶有故障轉移的主從集羣。是從現有的主從模式演變而來,增長了自動故障轉移和節點成員自動恢復。MongoDB複製集模式中沒有固定的主結點,在啓動後,多個服務節點間將自動選舉產生一個主結點。該主結點被稱爲primary,一個或多個從結點被稱爲secondaries。primary結點基本上就是master結點,不一樣之處在於primary結點在不一樣時間多是不一樣的服務器。若是當前的主結點失效了,複製集中的其他結點將會試圖選出一個新的主結點。linux

MongoDB複製集模式的好處:mongodb

  • 一切自動化。首先,複製集模式自己作了大量的管理工做,自動管理從節點,確保數據不會不一致。
  • 主節點掛掉後,會自動判斷集羣中的服務器並進行故障轉移,推舉新的主節點。
  • 一個複製集集羣支持1-7臺服務器,在一個複製集中各個服務器數據保持徹底一致。

在一個MongoDB複製集集羣中,各個服務器有如下幾種狀態:shell

  • Primary 主節點,一個複製集有且僅有一臺服務器處於Primary狀態,只有主節點纔對外提供讀寫服務。若是主節點掛掉,複製集將投票選出一個備節點成爲新的主節點。
  • Secondary 備用節點,複製集容許有多臺Secondary,每一個備用節點的數據與主節點的數據是徹底同步的。Recovering 恢復中,當複製集中某臺服務器掛掉或者掉線後數據沒法同步,從新恢復服務後從其餘成員複製數據,這時就處於恢復過程,數據同步後,該節點又回到備用狀態。
  • Arbiter 仲裁節點,該類節點能夠不用單獨存在,若是配置爲仲裁節點,就主要負責在複本集中監控其餘節點狀態,投票選出主節點。該節點將不會用於存放數據。若是沒有仲裁節點,那麼投票工做將由全部節點共同進行。
  • Down 無效節點,當服務器掛掉或掉線時就會處於該狀態。複製集的從節點讀請求,也是在各個Driver層設置slaveOk的值來實現的。

如上介紹所知,mongodb中的複製能夠在多臺服務器中同步數據。複製提供了冗餘和增長了數據的高可用性,防止單個節點易丟失數據的可能性,也能夠用來進行讀寫分離提升客戶端操做性能。複製集中各節點的mongodb實例有相同的數據集副本。主節點能夠接收客戶端全部寫操做記錄到日誌中,從庫複製主庫的操做日誌記錄應用到其數據庫中。一個客戶端只能有一個主節點,若是主節點不可用(10秒內沒法鏈接),複製集中將選一個成員節點做爲主節點。數據庫

MongoDB主備+仲裁的基本結構以下:vim

主節點(Primary)
在複製集中,主節點是惟一可以接收寫請求的節點。MongoDB在主節點進行寫操做,並將這些操做記錄到主節點的oplog中。而從節點將會從oplog複製到其本機,並將這些操做應用到本身的數據集上。(複製集最多隻能擁有一個主節點)
從節點(Secondaries)
從節點經過應用主節點傳來的數據變更操做來保持其數據集與主節點一致。從節點也能夠經過增長額外參數配置來對應特殊需求。例如,從節點能夠是non-voting或是priority 0.
仲裁節點(ARBITER)
仲裁節點即投票節點,其自己並不包含數據集,且也沒法晉升爲主節點。可是,旦當前的主節點不可用時,投票節點就會參與到新的主節點選舉的投票中。仲裁節點使用最小的資源而且不要求硬件設備。投票節點的存在使得複製集能夠以偶數個節點存在,而無需爲複製集再新增節點 不要將投票節點運行在複製集的主節點或從節點機器上。 投票節點與其餘 複製集節點的交流僅有:選舉過程當中的投票,心跳檢測和配置數據。這些交互都是不加密的。bash

心跳檢測
複製集成員每兩秒向複製集中其餘成員進行心跳檢測。若是某個節點在10秒內沒有返回,那麼它將被標記爲不可用。服務器

MongoDB副本集是有故障恢復功能的主從集羣,由一個primary節點和一個或多個secondary節點組成:
節點同步過程: Primary節點寫入數據,Secondary經過讀取Primary的oplog獲得複製信息,開始複製數據而且將複製信息寫入到本身的oplog。若是某個操做失敗,則備份節點中止從當前數據源複製數據。若是某個備份節點因爲某些緣由掛掉了,當從新啓動後,就會自動從oplog的最後一個操做開始同步,同步完成後,將信息寫入本身的oplog,因爲複製操做是先複製數據,複製完成後再寫入oplog,有可能相同的操做會同步兩份,不過MongoDB在設計之初就考慮到這個問題,將oplog的同一個操做執行屢次,與執行一次的效果是同樣的。app

通俗理解:當Primary節點完成數據操做後,Secondary會作出一系列的動做保證數據的同步:
- 檢查本身local庫的oplog.rs集合,找出最近的時間戳。
- 檢查Primary節點local庫oplog.rs集合,找出大於此時間戳的記錄。
- 將找到的記錄插入到本身的oplog.rs集合中,並執行這些操做。dom

副本集的同步和主從同步同樣,都是異步同步的過程,不一樣的是副本集有個自動故障轉移的功能。其原理是:slave端從primary端獲取日誌,而後在本身身上徹底順序的執行日誌所記錄的各類操做(該日誌是不記錄查詢操做的),這個日誌就是local數據 庫中的oplog.rs表,默認在64位機器上這個表是比較大的,佔磁盤大小的5%,oplog.rs的大小能夠在啓動參數中設 定:–oplogSize 1000,單位是M。異步

注意:在副本集的環境中,要是全部的Secondary都宕機了,只剩下Primary。最後Primary會變成Secondary,不能提供服務。

下面簡單介紹下MongoDB 副本集的部署過程:

1)服務器信息
sign-mongo01.wangshibo.cn  172.16.51.216   Primary
sign-mongo02.wangshibo.cn  172.16.51.217   Secondary
sign-mongo03.wangshibo.cn  172.16.51.218   Arbiter

三臺服務器均設置好主機名,關閉iptables及selinux(略)

2)在3臺服務器文件hosts文件中都添加如下3行:
[root@sign-mongo01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.51.216   sign-mongo01.wangshibo.cn
172.16.51.217   sign-mongo02.wangshibo.cn
172.16.51.218   sign-mongo03.wangshibo.cn 

3)安裝部署mongodb(三臺機器都安裝)
下載地址:https://www.mongodb.org/dl/linux/x86_64-rhel62
[app@sign-mongo01 software]$ pwd
/data/software
[app@sign-mongo01 software]$ ls
mongodb-linux-x86_64-rhel62-v3.2-latest.tgz
[app@sign-mongo01 software]$ tar -zvxf mongodb-linux-x86_64-rhel62-v3.2-latest.tgz 
[app@sign-mongo01 software]$ mv mongodb-linux-x86_64-rhel62-3.2.17-34-g4c1bae566c /data/mongodb
[app@sign-mongo01 software]$ cd /data/mongodb/
[app@sign-mongo01 mongodb]$ mkdir data
[app@sign-mongo01 mongodb]$ mkdir log
[app@sign-mongo01 mongodb]$ vim mongodb.conf
pidfilepath=/data/mongodb/log/mongod.pid
logpath=/data/mongodb/log/mongod.log
dbpath=/data/mongodb
logappend=true
bind_ip=172.16.51.216
port=27017
fork=true
replSet=rs0

備節點的mongodb.conf配置文件分別爲:
[app@sign-mongo02 mongodb]$ vim mongodb.conf
pidfilepath=/data/mongodb/log/mongod.pid
logpath=/data/mongodb/log/mongod.log
dbpath=/data/mongodb
logappend=true
bind_ip=172.16.51.217
port=27018
fork=true
replSet=rs0

其中:replSet=rs0  #表示複製集名稱:rs0

啓動主備服務器的mongodb
[app@sign-mongo01 ~]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 7317
child process started successfully, parent exiting
[app@sign-mongo01 mongodb]$ ps -ef|grep mongodb
app       7317     1  0 21:38 ?        00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
app       7342  7254  0 21:38 pts/1    00:00:00 grep mongodb
[app@sign-mongo01 mongodb]$ lsof -i:27017
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  7317  app    6u  IPv4  27011      0t0  TCP sign-mongo01.wangshibo.cn:27017 (LISTEN)

[app@sign-mongo02 mongodb]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 9725
child process started successfully, parent exiting
[app@sign-mongo02 mongodb]$ lsof -i:27018
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  9725  app    6u  IPv4  27191      0t0  TCP sign-mongo02.wangshibo.cn:27018 (LISTEN)

設置mongodb的環變量
[root@sign-mongo01 src]# vim /etc/profile
......
export PATH=$PATH:/data/mongodb/bin
[root@sign-mongo01 src]# source /etc/profile

登陸到mongodb中:
[app@sign-mongo01 ~]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017/test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
Server has startup warnings: 
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] 
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] 
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:38:18.063+0800 I CONTROL  [initandlisten] 
> 

初始化複製集:(集合爲:"rs0" ;第一個成員爲:"sign-mongo01.wangshibo.cn:27017" 
> rs.initiate({_id: "rs0",members: [{ _id: 0 , host: "sign-mongo01.wangshibo.cn:27017" }]})
{ "ok" : 1 }
rs0:OTHER>                    //接着回車,顯示這個節點爲Primary主節點
rs0:PRIMARY>

接着添加另1個成員:
rs0:PRIMARY> rs.add("sign-mongo02.wangshibo.cn:27018")
{ "ok" : 1 }

查當作員信息 (或者使用 db.isMaster() )
rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2017-11-22T13:55:28.446Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1031,
            "optime" : {
                "ts" : Timestamp(1511358895, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-11-22T13:54:55Z"),
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1511358843, 2),
            "electionDate" : ISODate("2017-11-22T13:54:03Z"),
            "configVersion" : 2,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 32,
            "optime" : {
                "ts" : Timestamp(1511358895, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-11-22T13:54:55Z"),
            "lastHeartbeat" : ISODate("2017-11-22T13:55:27.684Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-22T13:55:27.827Z"),
            "pingMs" : NumberLong(0),
            "configVersion" : 2
        }
    ],
    "ok" : 1
}


或者使用該方法查看,結果也是同樣:
rs0:PRIMARY> use admin
switched to db admin
rs0:PRIMARY> db.runCommand( { replSetGetStatus : 1 } )  
{
    "set" : "rs0",
    "date" : ISODate("2017-11-23T01:12:20.701Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 41643,
            "optime" : {
                "ts" : Timestamp(1511358895, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-11-22T13:54:55Z"),
            "electionTime" : Timestamp(1511358843, 2),
            "electionDate" : ISODate("2017-11-22T13:54:03Z"),
            "configVersion" : 2,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 40645,
            "optime" : {
                "ts" : Timestamp(1511358895, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-11-22T13:54:55Z"),
            "lastHeartbeat" : ISODate("2017-11-23T01:12:19.418Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T01:12:16.225Z"),
            "pingMs" : NumberLong(0),
            "configVersion" : 2
        }
    ],
    "ok" : 1
}
rs0:PRIMARY> 

詳細說明以下:
"_id" :  #集羣中節點編號  
"name" :  #成員服務器名稱及端口  
"health" :  #表示成員中的健康狀態(0:down;1:up)  
"state" :  #爲0~10,表示成員的當前狀態  
"stateStr" :  #描述該成員是主庫(PRIMARY)仍是備庫(SECONDARY)  
"uptime" :  #該成員在線時間(秒)  
"optime" :  #成員最後一次應用日誌(oplog)的信息  
"optimeDate" :  #成員最後一次應用日誌(oplog)的時間  
"electionTime" :  #當前primary從操做日誌中選舉信息  
"electionDate" :  #當前primary被選定爲primary的日期  
"configVersion" :  #mongodb版本  
"self" :  #爲true 表示當前節點  

4)測試操做。在主庫中,能夠任意操做:
rs0:PRIMARY> show dbs
local  0.000GB
rs0:PRIMARY> use mydb      //切換到要建立的數據庫
switched to db mydb
rs0:PRIMARY> show dbs      //use只是轉到相關數據庫,此時並無作任何操做,因此並不會建立相應的數據庫,只有當真正的操做了一次數據庫就會自動建立。
local  0.000GB
rs0:PRIMARY> db.stats();
{
    "db" : "mydb",
    "collections" : 0,
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 0,
    "numExtents" : 0,
    "indexes" : 0,
    "indexSize" : 0,
    "fileSize" : 0,
    "ok" : 1
}
rs0:PRIMARY> db.coll.insert({"id":1}) 
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.coll.find() 
{ "_id" : ObjectId("5a162222991b83743942d169"), "id" : 1 }
rs0:PRIMARY> db.coll.remove({"id":1}) 
WriteResult({ "nRemoved" : 1 })
rs0:PRIMARY> show dbs
local  0.000GB
mydb   0.000GB


如今到備庫中
172.16.51.217 (sign-mongo02.wangshibo.cn )
查看分庫數據庫目錄,發現多了數據庫,數據庫與主庫(172.16.51.216)一致!是主庫同步過來的。
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018/test
Server has startup warnings: 
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 

在副本服務器中登陸其本地數據庫,發現能夠鏈接,可是沒法讀寫操做:
rs0:SECONDARY> show dbs
2017-11-23T09:25:35.961+0800 E QUERY    [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:781:19
shellHelper@src/mongo/shell/utils.js:671:15
@(shellhelp2):1:1
rs0:SECONDARY>

從庫開啓讀操做(此時能夠測試主庫插入,從庫查看,同步正常):
rs0:SECONDARY> rs.slaveOk();  
rs0:SECONDARY> show dbs
local  0.000GB
mydb   0.000GB


5)如今模擬主庫不可用,將主節點服務中止:
[app@sign-mongo01 mongodb]$ pkill -9 mongod
[app@sign-mongo01 mongodb]$ ps -ef|grep mongodb
app       9524  9398  0 09:32 pts/0    00:00:00 grep mongodb

到備節點172.16.51.217 中登陸mongodb,查看複製集狀態:
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018/test
Server has startup warnings: 
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 
rs0:SECONDARY> rs.status() 
{
    "set" : "rs0",
    "date" : ISODate("2017-11-23T01:33:29.688Z"),
    "myState" : 2,
    "term" : NumberLong(1),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 0,
            "state" : 8,
            "stateStr" : "(not reachable/healthy)",
            "uptime" : 0,
            "optime" : {
                "ts" : Timestamp(0, 0),
                "t" : NumberLong(-1)
            },
            "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
            "lastHeartbeat" : ISODate("2017-11-23T01:33:28.732Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T01:32:28.099Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "Connection refused",
            "configVersion" : -1
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 42412,
            "optime" : {
                "ts" : Timestamp(1511399985, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2017-11-23T01:19:45Z"),
            "infoMessage" : "could not find member to sync from",
            "configVersion" : 2,
            "self" : true
        }
    ],
    "ok" : 1
}

有上面可看出,主節點刪除服務進程,primary並無切換到備節點上:
再次啓動主節點的mongodb服務,發現primary才自動切換回到主節點:
[app@sign-mongo01 mongodb]$ nohup /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
nohup: ignoring input and appending output to `nohup.out'
[app@sign-mongo01 mongodb]$ ps -ef|grep mongodb
app       9538     1  8 09:37 ?        00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
app       9610  9398  0 09:37 pts/0    00:00:00 grep mongodb
[app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017/test
Server has startup warnings: 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2017-11-23T01:38:19.631Z"),
    "myState" : 1,
    "term" : NumberLong(2),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 54,
            "optime" : {
                "ts" : Timestamp(1511401058, 2),
                "t" : NumberLong(2)
            },
            "optimeDate" : ISODate("2017-11-23T01:37:38Z"),
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1511401058, 1),
            "electionDate" : ISODate("2017-11-23T01:37:38Z"),
            "configVersion" : 2,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 53,
            "optime" : {
                "ts" : Timestamp(1511401058, 2),
                "t" : NumberLong(2)
            },
            "optimeDate" : ISODate("2017-11-23T01:37:38Z"),
            "lastHeartbeat" : ISODate("2017-11-23T01:38:18.072Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T01:38:18.596Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "sign-mongo01.wangshibo.cn:27017",
            "configVersion" : 2
        }
    ],
    "ok" : 1
}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如今開始部署仲裁節點sign-mongo03.wangshibo.cn
[app@sign-mongo03 ~]$ mkdir /data/mongodb/arbiter
[app@sign-mongo03 ~]$ ll -d /data/mongodb/arbiter
drwxrwxr-x 2 app app 4096 Nov 23 09:39 /data/mongodb/arbiter

本案例是在普通用戶app帳號下部署的,權限都是app.app。
若是是在root帳號下部署,那麼須要將mongodb數據目錄下的文件所有設置mongodb.mongodb權限

mongodb.conf配置:
[app@sign-mongo03 ~]$ vim /data/mongodb/mongodb.conf
pidfilepath=/data/mongodb/log/mongod.pid
logpath=/data/mongodb/log/mongod.log
dbpath=/data/mongodb/arbiter
logappend=false
bind_ip=172.16.51.218
port=27019
fork=true
replSet=rs0

接着重啓服務:
[app@sign-mongo03 ~]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 9217
child process started successfully, parent exiting
[app@sign-mongo03 ~]$ ps -ef|grep mongo
app       9217     1  1 09:46 ?        00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf
app       9242  9158  0 09:46 pts/0    00:00:00 grep mongo
[app@sign-mongo03 ~]$ lsof -i:27019
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  9217  app    6u  IPv4  37321      0t0  TCP sign-mongo03.wangshibo.cn:27019 (LISTEN)

而後在Paimary主節點sign-mongo01.wangshibo.cn的mongodb中添加仲裁節點並查看結果
[app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.216:27017/test
Server has startup warnings: 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:37:26.467+0800 I CONTROL  [initandlisten] 
rs0:PRIMARY> rs.addArb("sign-mongo03.wangshibo.cn:27019")
{ "ok" : 1 }
rs0:PRIMARY> db.isMaster() 
{
    "hosts" : [
        "sign-mongo01.wangshibo.cn:27017",
        "sign-mongo02.wangshibo.cn:27018"
    ],
    "arbiters" : [
        "sign-mongo03.wangshibo.cn:27019"
    ],
    "setName" : "rs0",
    "setVersion" : 4,
    "ismaster" : true,
    "secondary" : false,
    "primary" : "sign-mongo01.wangshibo.cn:27017",
    "me" : "sign-mongo01.wangshibo.cn:27017",
    "electionId" : ObjectId("7fffffff0000000000000003"),
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2017-11-23T01:59:03.554Z"),
    "maxWireVersion" : 4,
    "minWireVersion" : 0,
    "ok" : 1
}
rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2017-11-23T02:00:26.312Z"),
    "myState" : 1,
    "term" : NumberLong(3),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 368,
            "optime" : {
                "ts" : Timestamp(1511402420, 1),
                "t" : NumberLong(3)
            },
            "optimeDate" : ISODate("2017-11-23T02:00:20Z"),
            "electionTime" : Timestamp(1511402069, 1),
            "electionDate" : ISODate("2017-11-23T01:54:29Z"),
            "configVersion" : 5,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 367,
            "optime" : {
                "ts" : Timestamp(1511402420, 1),
                "t" : NumberLong(3)
            },
            "optimeDate" : ISODate("2017-11-23T02:00:20Z"),
            "lastHeartbeat" : ISODate("2017-11-23T02:00:26.306Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T02:00:26.309Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "sign-mongo01.wangshibo.cn:27017",
            "configVersion" : 5
        },
        {
            "_id" : 3,
            "name" : "sign-mongo03.wangshibo.cn:27019",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 93,
            "lastHeartbeat" : ISODate("2017-11-23T02:00:26.306Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T02:00:25.306Z"),
            "pingMs" : NumberLong(0),
            "configVersion" : 5
        }
    ],
    "ok" : 1
}


至此,添加完成!!
再次測試主備切換。關閉172.16.51.216(primary)中刪除服務進程:
[app@sign-mongo01 mongodb]$ pkill -9 mongod
[app@sign-mongo01 mongodb]$ ps -ef|grep mongod
app       9664  9398  0 09:50 pts/0    00:00:00 grep mongod
[app@sign-mongo01 mongodb]$ lsof -i:27017
[app@sign-mongo01 mongodb]$ 

而後到172.16.51.217:27018(secondary)查看,發現primary已經切換爲172.16.51.217
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.217:27018/test
Server has startup warnings: 
2017-11-22T21:46:38.417+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-22T21:46:38.418+0800 I CONTROL  [initandlisten] 
rs0:PRIMARY> rs.status()
{
    "set" : "rs0",
    "date" : ISODate("2017-11-23T02:01:17.762Z"),
    "myState" : 1,
    "term" : NumberLong(4),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "sign-mongo01.wangshibo.cn:27017",
            "health" : 0,
            "state" : 8,
            "stateStr" : "(not reachable/healthy)",
            "uptime" : 0,
            "optime" : {
                "ts" : Timestamp(0, 0),
                "t" : NumberLong(-1)
            },
            "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
            "lastHeartbeat" : ISODate("2017-11-23T02:01:17.316Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T02:01:04.327Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "Connection refused",
            "configVersion" : -1
        },
        {
            "_id" : 1,
            "name" : "sign-mongo02.wangshibo.cn:27018",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 44080,
            "optime" : {
                "ts" : Timestamp(1511402475, 2),
                "t" : NumberLong(4)
            },
            "optimeDate" : ISODate("2017-11-23T02:01:15Z"),
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1511402475, 1),
            "electionDate" : ISODate("2017-11-23T02:01:15Z"),
            "configVersion" : 5,
            "self" : true
        },
        {
            "_id" : 3,
            "name" : "sign-mongo03.wangshibo.cn:27019",
            "health" : 1,
            "state" : 7,
            "stateStr" : "ARBITER",
            "uptime" : 145,
            "lastHeartbeat" : ISODate("2017-11-23T02:01:17.315Z"),
            "lastHeartbeatRecv" : ISODate("2017-11-23T02:01:15.316Z"),
            "pingMs" : NumberLong(0),
            "configVersion" : 5
        }
    ],
    "ok" : 1
}
rs0:PRIMARY> show dbs
local  0.000GB
mydb   0.000GB

有上面信息可知,添加仲裁節點後,primary能正常啓動切換了!~

如今看看arbiter,鏈接到172.16.51.218:27019
[app@sign-mongo03 ~]$ mongo 172.16.51.218:27019
MongoDB shell version: 3.2.17-34-g4c1bae566c
connecting to: 172.16.51.218:27019/test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
Server has startup warnings: 
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] 
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] 
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-11-23T09:58:34.978+0800 I CONTROL  [initandlisten] 
rs0:ARBITER> rs.slaveOk(); 
rs0:ARBITER> db.isMaster()
{
    "hosts" : [
        "sign-mongo01.wangshibo.cn:27017",
        "sign-mongo02.wangshibo.cn:27018"
    ],
    "arbiters" : [
        "sign-mongo03.wangshibo.cn:27019"
    ],
    "setName" : "rs0",
    "setVersion" : 5,
    "ismaster" : false,
    "secondary" : false,
    "primary" : "sign-mongo02.wangshibo.cn:27018",
    "arbiterOnly" : true,
    "me" : "sign-mongo03.wangshibo.cn:27019",
    "maxBsonObjectSize" : 16777216,
    "maxMessageSizeBytes" : 48000000,
    "maxWriteBatchSize" : 1000,
    "localTime" : ISODate("2017-11-23T02:03:33.874Z"),
    "maxWireVersion" : 4,
    "minWireVersion" : 0,
    "ok" : 1
}
rs0:ARBITER> show dbs
local  0.000GB

arbiter 最爲仲裁者,沒有數據副本存儲在本地,能讀取複製集的信息。
-------------------------------------------------------------------------------------------------
在primary主庫上,建立locs數據庫,該庫的用戶名爲locsopr,密碼爲locsopr@123
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018
......
rs0:PRIMARY> use locs
switched to db locs
rs0:PRIMARY> db.createUser({user:"locsopr",pwd :"locsopr@123",roles:["readWrite"]})
Successfully added user: { "user" : "locsopr", "roles" : [ "readWrite" ] }
rs0:PRIMARY> show users;          //查看當前庫下的用戶名
{
    "_id" : "locs.locsopr",
    "user" : "locsopr",
    "db" : "locs",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "locs"
        }
    ]
}


使用上面的用戶登陸primary主庫
[app@sign-mongo02 ~]$ mongo 172.16.51.217:27018/locs -ulocsopr -plocsopr@123
.........
rs0:PRIMARY> show users
{
    "_id" : "locs.locsopr",
    "user" : "locsopr",
    "db" : "locs",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "locs"
        }
    ]
}
rs0:PRIMARY> show dbs
admin  0.000GB
local  0.000GB
rs0:PRIMARY> 

再登陸從庫看下:
[app@sign-mongo01 ~]$ mongo 172.16.51.216:27017/locs -ulocsopr -plocsopr@123
.......
rs0:SECONDARY> rs.slaveOk();
rs0:SECONDARY> show users
{
    "_id" : "locs.locsopr",
    "user" : "locsopr",
    "db" : "locs",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "locs"
        }
    ]
}
rs0:SECONDARY> show dbs
admin  0.000GB
local  0.000GB

-------------------------------------------------------------------------------------------------------------------------------------------------------
上面介紹的是三臺mongodb節點:一主一備一仲裁,這樣,主節點掛了後,經過仲裁機制將primary自動切換到備機上!
若是上面的三臺mongodb節點:一主兩備,沒有仲裁節點,那麼主節點掛了後,primary會自動切換到其他兩臺備節點中的一臺上!

一主兩從(端口分別爲2701七、2701八、27019)的mongodb配置和上面一主一從(端口分別爲2701七、27018)的配置同樣。
多加的一個從節點,在主節點登錄mongodb,使用rs.add命令將這個成員加到集羣中便可!

一主兩從的模式,好比:
主節點sign-mongo01.wangshibo.cn的mongodb服務程序掛了後,另外兩個從節點中的一個(好比sign-mongo02.wangshibo.cn)會自動變成primary主節點,
另外一個節點sign-mongo03.wangshibo.cn則是新的主節點(sign-mongo02.wangshibo.cn)的從節點。

++++++++++++++++++++++++++++++若是想讓切換回原來的主節點,作法以下+++++++++++++++++++++++++++++++
1)恢復原來的主節點sign-mongo01.wangshibo.cn的mongodb服務,使用命令rs.status() 確認數據集成員運行正常。
2)到次節點sign-mongo03.wangshibo.cn中登陸mongodb,運行freeze使其120內不會變爲主節點。  
> rs.freeze(120)  
3) 到新的主節點sign-mongo02.wangshibo.cn中強制切換主節點,stepDown將阻止長事務和寫入操做  
> rs.stepDown(120) 
4)此時sign-mongo01.wangshibo.cn節點變成primary主節點。使用rs.status()命令能夠查看到集羣狀態。

+++++++++++++++++++++++若要使某個節點永遠不會變爲主節點,設置優先級爲0便可+++++++++++++++++++++++
登錄當前主節點的mongodb,執行下面操做:
rs0:PRIMARY> cfg = rs.conf()  
rs0:PRIMARY> cfg.members[0].priority = 0.5  
rs0:PRIMARY> cfg.members[1].priority = 0.5  
rs0:PRIMARY> cfg.members[2].priority = 0  
rs0:PRIMARY> rs.reconfig(cfg)  

說明:
其中成員編號0/1/2爲 rs.status()中的 "_id"值  
members[2]表示sign-mongo03.wangshibo.cn,則它將永遠不會變成主節點!由於優先級設置爲0了!

++++++++++++++++++++++++++++++++移除一個複製成員(兩種方法)++++++++++++++++++++++++++++++++++++
登錄當前主節點的mongodb,執行下面操做:
rs0:PRIMARY> rs.remove("sign-mongo03.wangshibo.cn:27019")  
rs0:PRIMARY> rs.conf()  

或者:  
rs0:PRIMARY> cfg = rs.conf()  
rs0:PRIMARY> cfg.members.splice(2,1)  
rs0:PRIMARY> rs.reconfig(cfg)  

移除後到移除的節點服務器(即sign-mongo03.wangshibo.cn),更改配置文件mongod.conf
#replSet=rs0       //將這一行註釋
而後再重啓mongodb服務,這就完成了移除(數據庫文件仍保留在當前服務器)。
相關文章
相關標籤/搜索