1. 程式人生 > >MongoDB復制集 (主從復制)

MongoDB復制集 (主從復制)

inux eid ora sig lis 定期 recv .org time

MongoDB 復制集

MongoDB復制是將數據同步到多個服務器的過程;
復制集提供了數據的冗余備份並提高了數據的可用性,通常可以保證數據的安全性;
復制集還允許您從硬件故障和服務中斷中恢復數據。

什麽是復制集?

  • 保障數據的安全性
  • 數據高可用性 (24*7)
  • 災難恢復
  • 無需停機維護(如備份,重建索引,壓縮)
  • 分布式讀取數據
  • 副本集對應用層是透明的

MongoDB復制集的工作原理

  1. mongodb的復制集至少需要兩個節點。其中一個是主節點,負責處理客戶端請求,其余的都是從節點,負責復制主節點上的數據。
  2. mongodb各個節點常見的搭配方式為:一主一從、一主多從。
  3. 主節點記錄在其上的所有操作oplog,從節點定期輪詢主節點獲取這些操作,然後對自己的數據副本執行這些操作,從而保證從節點的數據與主節點一致。

MongoDB復制結構圖如下所示:

技術分享圖片

(以上圖片引用網址:http://www.runoob.com/mongodb/mongodb-replication.html )

以上結構圖中,客戶端從主節點讀取數據,在客戶端寫入數據到主節點時,主節點與從節點進行數據交互保障數據的一致性。

復制集的特點:

  • N 個節點的集群
  • 任何節點可作為主節點
  • 所有寫入操作都在主節點上
  • 自動故障轉移
  • 自動恢復

如何部署MongoDB復制集?

在同一臺服務器上創建MongoDB的多實例(4個實例)來做MongoDB主從的實驗。

至於如何安裝MongoDB?請參考之前博文 Linux 平臺安裝MongoDB 4.0(最新版)

開始部署

1.創建4個MongoDB的實例

#創建各實例的數據目錄
mkdir -p /data/mongodb/mongodb{1,2,3,4}

#創建實例配置目錄
mkdir -p /data/conf/

#創建實例的日誌目錄
mkdir -p /data/logs/

#創建各實例的日誌文件
touch  /data/logs/mongodb{1,2,3,4}.log

#賦予日誌文件權限777
chmod 777 /data/logs/*.log

2.編輯mongodb1.conf配置文件,開啟復制集功能並配置replSetName參數

vim /data/mongodb/mongodb1.conf

#mongod.conf

#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb1.log //mongodb1的日誌文件路徑
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb1/ //mongodb1的數據文件路徑
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27017 //mongodb1的進程號
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //刪除“#”,開啟復制集功能
replSetName: test-rc //名稱為test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:

3.復制默認mongodb1.conf配置文件,生成另外三份實例的配置文件

#復制默認實例的配置文件

cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb2.conf
cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb3.conf
cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb4.conf

4.分別修改mongodb2.conf、mongodb3.conf、mongodb4.conf配置文件,如下

MongoDB2配置文件
cat /data/conf/mongodb2.conf

#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb2.log //mongodb2的日誌文件路徑
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb2/ //mongodb2的數據文件路徑
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27018 //mongodb2的進程號
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //刪除“#”,開啟復制集功能
replSetName: test-rc #名稱為test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:

MongoDB3配置文件
cat /data/conf/mongodb3.conf

#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb3.log //mongodb3的日誌文件路徑
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb3/ //mongodb3的數據文件路徑
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27019 //mongodb3的進程號
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //刪除“#”,開啟復制集功能
replSetName: test-rc #名稱為test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:

MongoDB4配置文件
cat /data/conf/mongodb4.conf

#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb4.log //mongodb4的日誌文件路徑
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb4/ //mongodb4的數據文件路徑
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27020 //mongodb4的進程號
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //刪除“#”,開啟復制集功能
replSetName: test-rc //名稱為test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:

5. 啟動mongodb多實例

mongod -f /data/conf/mongodb1.conf
mongod -f /data/conf/mongodb2.conf
mongod -f /data/conf/mongodb3.conf
mongod -f /data/conf/mongodb4.conf

檢查mongod的進程信息

[root@localhost conf]# netstat -tunlp | grep mongod

技術分享圖片

6.開始配置三個節點的復制集

6.1 登錄默認MongoDB(默認端口號為:27017)
mongo
6.2 查看復制集的狀態信息
> rs.status()

技術分享圖片

6.3 定義cfg初始化參數(這裏先加入三臺,另一臺後面實現添加節點功能)
> cfg={"_id":"test-rc","members":[{"_id":0,"host":"192.168.100.100:27017"},{"_id":1,"host":"192.168.100.100:27018"},{"_id":2,"host":"192.168.100.100:27019"}]}

技術分享圖片

6.4 啟動復制集功能(初始化配置時保證從節點沒有數據)
> rs.initiate(cfg)

技術分享圖片

6.5 查看復制集的狀態信息
test-rc:PRIMARY> rs.status()

{
"set" : "test-rc",
"date" : ISODate("2018-07-14T04:46:58.710Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1531543618, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1531543618, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1531543618, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1531543618, 1),
"t" : NumberLong(1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1531543608, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.100.100:27017",
"health" : 1, //健康狀態
"state" : 1, //1:為主節點 ; 2:為從節點
"stateStr" : "PRIMARY", //主節點
"uptime" : 2886,
"optime" : {
"ts" : Timestamp(1531543618, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-07-14T04:46:58Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1531543426, 1),
"electionDate" : ISODate("2018-07-14T04:43:46Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.100.100:27018",
"health" : 1, //健康狀態
"state" : 2, //1:為主節點 ; 2:為從節點
"stateStr" : "SECONDARY", //從節點
"uptime" : 202,
"optime" : {
"ts" : Timestamp(1531543608, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1531543608, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-07-14T04:46:48Z"),
"optimeDurableDate" : ISODate("2018-07-14T04:46:48Z"),
"lastHeartbeat" : ISODate("2018-07-14T04:46:56.765Z"),
"lastHeartbeatRecv" : ISODate("2018-07-14T04:46:57.395Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.100:27017",
"syncSourceHost" : "192.168.100.100:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.100.100:27019",
"health" : 1, //健康狀態
"state" : 2, //1:為主節點 ; 2:為從節點
"stateStr" : "SECONDARY", //從節點
"uptime" : 202,
"optime" : {
"ts" : Timestamp(1531543608, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1531543608, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-07-14T04:46:48Z"),
"optimeDurableDate" : ISODate("2018-07-14T04:46:48Z"),
"lastHeartbeat" : ISODate("2018-07-14T04:46:56.769Z"),
"lastHeartbeatRecv" : ISODate("2018-07-14T04:46:57.441Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.100:27017",
"syncSourceHost" : "192.168.100.100:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1531543618, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1531543618, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

特別提醒:主節點在192.168.100.100:27017節點上

7. 添加節點

> rs.add("192.168.100.100:27020")

技術分享圖片

查看復制集的狀態信息
> rs.status()

技術分享圖片

8. 刪除節點

> rs.remove("192.168.100.100:27018")

技術分享圖片

查看復制集的狀態信息
> rs.status()

發現192.168.100.100:27018節點已經沒有相關信息了

9. 故障轉移切換

9.1 退出MongoDB
test-rc:PRIMARY> exit
9.2 查看mongod進程信息
netstat -tunlp | grep mongod

技術分享圖片

可以查看到共有4個實例的進程信息

9.3 結束主節點:端口號為27017的進程,檢查是否能夠自動切換
kill -9 48211        

技術分享圖片

9.4 登錄MongoDB端口號為27019的實例
mongo --port 27019
9.5 查看各節點狀態信息
> rs.status()

{
"_id" : 2,
"name" : "192.168.100.100:27019",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1547,
"optime" : {
"ts" : Timestamp(1531544567, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-07-14T05:02:47Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1531544345, 1),
"electionDate" : ISODate("2018-07-14T04:59:05Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 3,
"name" : "192.168.100.100:27020",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 700,
"optime" : {
"ts" : Timestamp(1531544567, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1531544567, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-07-14T05:02:47Z"),
"optimeDurableDate" : ISODate("2018-07-14T05:02:47Z"),
"lastHeartbeat" : ISODate("2018-07-14T05:02:56.150Z"),
"lastHeartbeatRecv" : ISODate("2018-07-14T05:02:56.289Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.100:27019",
"syncSourceHost" : "192.168.100.100:27019",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 3
}

特別提醒:主節點已經到192.168.100.100:27019節點上,說明主節點已經自動切換了

10. 手動切換主節點

10.1 暫停30s不參與選舉
test-rc:PRIMARY> rs.freeze(30)

{
"operationTime" : Timestamp(1531544867, 1),
"ok" : 0,
"errmsg" : "cannot freeze node when primary or running for election. state: Primary",
"code" : 95,
"codeName" : "NotSecondary",
"$clusterTime" : {
"clusterTime" : Timestamp(1531544867, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

10.2 交出主節點位置,維持從節點狀態不少於60秒,等待30秒使主節點和從節點日誌同步

test-rc:PRIMARY> rs.stepDown(60,30)

> test-rc:PRIMARY> rs.stepDown(60,30)

2018-07-14T01:08:07.326-0400 E QUERY [js] Error: error doing query: failed: network error while attempting to run command ‘replSetStepDown‘ on host ‘127.0.0.1:27019‘ :DB.prototype.runCommand@src/mongo/shell/db.js:168:1
br/>DB.prototype.runCommand@src/mongo/shell/db.js:168:1
br/>rs.stepDown@src/mongo/shell/utils.js:1398:12
2018-07-14T01:08:07.328-0400 I NETWORK [js] trying reconnect to 127.0.0.1:27019 failed
2018-07-14T01:08:07.329-0400 I NETWORK [js] reconnect 127.0.0.1:27019 ok

10.3 查看復制集的狀態信息
> test-rc:PRIMARY> rs.status()

{
"set" : "test-rc",
"date" : ISODate("2018-07-14T05:10:31.161Z"),
"myState" : 2,
"term" : NumberLong(3),
"syncingTo" : "192.168.100.100:27020",
"syncSourceHost" : "192.168.100.100:27020",
"syncSourceId" : 3,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"appliedOpTime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"durableOpTime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1531545018, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.100.100:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 70,
"optime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2018-07-14T05:10:28Z"),
"syncingTo" : "192.168.100.100:27020",
"syncSourceHost" : "192.168.100.100:27020",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.100.100:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 68,
"optime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"optimeDurable" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2018-07-14T05:10:28Z"),
"optimeDurableDate" : ISODate("2018-07-14T05:10:28Z"),
"lastHeartbeat" : ISODate("2018-07-14T05:10:30.079Z"),
"lastHeartbeatRecv" : ISODate("2018-07-14T05:10:31.094Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.100:27020",
"syncSourceHost" : "192.168.100.100:27020",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 3
},
{
"_id" : 3,
"name" : "192.168.100.100:27020",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 68,
"optime" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"optimeDurable" : {
"ts" : Timestamp(1531545028, 1),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2018-07-14T05:10:28Z"),
"optimeDurableDate" : ISODate("2018-07-14T05:10:28Z"),
"lastHeartbeat" : ISODate("2018-07-14T05:10:30.079Z"),
"lastHeartbeatRecv" : ISODate("2018-07-14T05:10:29.561Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1531544897, 1),
"electionDate" : ISODate("2018-07-14T05:08:17Z"),
"configVersion" : 3
}
],
"ok" : 1,
"operationTime" : Timestamp(1531545028, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1531545028, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

特別提醒:此刻主節點已經在192.168.100.100:27020節點上

MongoDB復制集 (主從復制)