您好,登錄后才能下訂單哦!
復制的原理
復制時基于啊哦做日志 oplog , 相當于 MySQL 中的二進制日志,只記錄發生改變的記錄。復制是將主節點的oplog 日志同步并應用到其他從節點的過程。
選舉的原理
節點類型分為標準(host)節點 、被動(passive)節點和仲裁(arbiter)節點。
(1)只有標準節點可能被選舉為活躍(primary)節點,有選舉權。被動節點有完整副本,不可能成為活躍節點,有選舉權。仲裁節點不復制數據,不可能成為活躍節點,只有選舉權。
(2)標準節點與被動節點的區別:primary 值高者是標準節點,低者則為被動節點。
(3)選舉規則是票數高者獲勝,primary 是優先權為 0~1000 的值,相當于額為增加 0~1000 的票數。選舉結果:票數高者獲勝;若票數相同,數據新者獲勝。
實驗部署
搭建配置4個 MongoDB 實例 mongodb 、mongpdb2 、mongodb3 、mongodb4 。 IP 地址:192.168.213.184
由于MongoDB 數據庫安裝好后,mongodb 為默認第一個實例,因此只要再搭建2 ,3,4 實例即可
1. 配置復制集
(1)創建數據文件和日志文件存儲路徑
[root@localhost ~]# mkdir -p /data/mongodb/mongodb{2,3,4} #創建數據庫文件2,3,4
[root@localhost ~]# cd /data/mongodb/
[root@localhost mongodb]# ls
mongodb2 mongodb3 mongodb4
[root@localhost mongodb]# mkdir logs
[root@localhost mongodb]# ls
logs mongodb2 mongodb3 mongodb4
[root@localhost mongodb]# cd logs/
[root@localhost logs]# touch mongodb{2,3,4}.log #在 /data/mongodb/logs/ 目錄下的日志存儲路徑
[root@localhost logs]# chmod - R 777 /data/mongodb/logs/*.log #修改目錄權限
[root@localhost logs]# ls -l
總用量 0
-rwxrwxrwx. 1 root root 0 9月 13 18:43 mongodb2.log
-rwxrwxrwx. 1 root root 0 9月 13 18:43 mongodb3.log
-rwxrwxrwx. 1 root root 0 9月 13 18:43 mongodb4.log
(2)配置實例1 的配置文件,啟用復制集名稱
[root@localhost logs]# vim /etc/mongod.conf
replication:
replSetName: abc #去掉注釋,指定復制集名稱(名稱隨便定義)
創建多實例配置文件
[root@localhost logs]# cp -p /etc/mongod.conf /etc/mongod2.conf 復制生成實例2 的配置文件
[root@localhost logs]# vim /etc/mongod2.confsystemLog:
destination: file
logAppend: true
path: /data/mongodb/logs/mongodb2.log #日志文件位置storage:
dbPath: /data/mongodb/mongodb2 #數據文件位置
journal:
enabled: trueport: 27018 #端口號,默認端口號為27017,因此實例2 的端口號要與之區別,實例3和4 依次往后排
配置其他實例,與實例2修改一樣,注意端口號
[root@localhost logs]# cp -p /etc/mongod2.conf /etc/mongod3.conf
[root@localhost logs]# cp -p /etc/mongod2.conf /etc/mongod4.conf
(3)啟動服務并查看端口是否開啟
[root@localhost logs]# mongod -f /etc/mongod.conf –shutdown #先關閉實例1 的服務,在開啟
killing process with pid: 3997 #進程號
[root@localhost logs]# mongod -f /etc/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 4867
child process started successfully, parent exiting
[root@localhost logs]# mongod -f /etc/mongod2.conf #啟動實例2 的服務
about to fork child process, waiting until server is ready for connections.
forked process: 4899
child process started successfully, parent exiting
[root@localhost logs]# mongod -f /etc/mongod3.conf #啟動實例3 的服務
about to fork child process, waiting until server is ready for connections.
forked process: 4927
child process started successfully, parent exiting
[root@localhost logs]# mongod -f /etc/mongod4.conf #啟動實例4 的服務
about to fork child process, waiting until server is ready for connections.
forked process: 4955查看節點端口是否開啟
[root@localhost logs]# netstat -ntap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:27019 0.0.0.0:* LISTEN 4927/mongod
tcp 0 0 0.0.0.0:27020 0.0.0.0:* LISTEN 4955/mongod
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 4867/mongod
tcp 0 0 0.0.0.0:27018 0.0.0.0:* LISTEN 4899/mongod
(4)查看各實例能否進入 mongodb 數據庫
[root@localhost logs]# mongo
MongoDB shell version v3.6.7
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.7[root@localhost logs]# mongo --port 27018
MongoDB shell version v3.6.7
connecting to: mongodb://127.0.0.1:27018/
MongoDB server version: 3.6.7
Server has startup warnings:[root@localhost logs]# mongo --port 27019
MongoDB shell version v3.6.7
connecting to: mongodb://127.0.0.1:27019/
MongoDB server version: 3.6.7
Server has startup warnings:[root@localhost logs]# mongo --port 27020
MongoDB shell version v3.6.7
connecting to: mongodb://127.0.0.1:27020/
MongoDB server version: 3.6.7
2 . 配置復制集的優先級
(1)登錄默認實例 mongo,重新配置4個節點 MongoDB 復制集,設置兩個標準節點,有個被動節點和一個仲裁節點,命令如下:
根據優先級確定節點: 優先級為 100的為標準節點,端口號為 27017和27018 ,優先級為0 的為被動節點,端口號為27019;仲裁節點為27020
> cfg={"_id":"abc","members":[{"_id":0,"host":"192.168.213.184:27017","priority":100},{"_id":1,"host":"192.168.213.184:27018","priority":100},{"_id":2,"host":"192.168.213.184:27019","priority":0},{"_id":3,"host":"192.168.213.184:27020","arbiterOnly":true}]}
{
"_id" : "abc",
"members" : [
{
"_id" : 0,
"host" : "192.168.213.184:27017", #標準節點,優先級為100
"priority" : 100
},
{
"_id" : 1,
"host" : "192.168.213.184:27018", #標準節點
"priority" : 100
},
{
"_id" : 2,
"host" : "192.168.213.184:27019", #被動節點,優先級為0
"priority" : 0
},
{
"_id" : 3,
"host" : "192.168.213.184:27020", #仲裁節點
"arbiterOnly" : true
}
]
}
> rs.initiate(cfg) # 初始化復制集
{
"ok" : 1,
"operationTime" : Timestamp(1536819122, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1536819122, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
(2)使用命令 rs.isMaster() 查看各節點身份
abc:PRIMARY> rs.isMaster()
{
"hosts" : [ #標準節點
"192.168.213.184:27017",
"192.168.213.184:27018"
],
"passives" : [ #被動節點
"192.168.213.184:27019"
],
"arbiters" : [ #仲裁節點
"192.168.213.184:27020"
],
"setName" : "abc",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.213.184:27017",
(3)此時默認實例已經被選舉為活躍(primary)節點,可以在數據庫中插入信息了。
abc:PRIMARY> use school #活躍節點(primory)
switched to db school
abc:PRIMARY> db.info.insert({"id":1,"name":"lili"}) #插入兩條信息
WriteResult({ "nInserted" : 1 })
abc:PRIMARY> db.info.insert({"id":2,"name":"tom"})
WriteResult({ "nInserted" : 1 })
(4)查看日志記錄所有操作,在默認數據庫 local 中的oplog.rs 查看
abc:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
school 0.000GB
abc:PRIMARY> use local #進入 local 數據庫
switched to db local
abc:PRIMARY> show collections #顯示
me
oplog.rs
replset.election
replset.minvalid
startup_log
system.replset
system.rollback.id
abc:PRIMARY> db.oplog.rs.find() #查看日志記錄所有操作
通過日志記錄,可以找到剛才加入的兩條信息
"school.info", "ui" : UUID("2b9c93b6-a58a-4021-a2b4-33f9b19925d8"), "wall" : ISODate("2018-09-13T06:24:44.537Z"), "o" : { "_id" : ObjectId("5b9a02aca106c3eab9c639e5"), "id" : 1, "name" : "lili" } }
{ "ts" : Timestamp(1536819899, 1), "t" : NumberLong(1), "h" : NumberLong("-1447313909384631008"), "v" : 2, "op" : "i", "ns" : "school.info", "ui" : UUID("2b9c93b6-a58a-4021-a2b4-33f9b19925d8"), "wall" : ISODate("2018-09-13T06:24:59.186Z"), "o" : { "_id" : ObjectId("5b9a02bba106c3eab9c639e6"), "id" : 2, "name" : "tom" } }
3.模擬節點故障,如果主節點出現故障,另一個標準節點會選舉成為新的主節點。
(1)先查看當前狀態,使用命令 rs.status()
abc:PRIMARY> rs.status()
"members" : [
{
"_id" : 0,
"name" : "192.168.213.184:27017", #標準節點,端口27017,作為主節點
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2481,
"optime" : {
"ts" : Timestamp(1536820334, 1),
"t" : NumberLong(1)
},{
"_id" : 1,
"name" : "192.168.213.184:27018", #標準節點 ,端口27018 為從節點
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1213,
"optime" : {
"ts" : Timestamp(1536820324, 1),
"t" : NumberLong(1)
},{
"_id" : 2,
"name" : "192.168.213.184:27019", #被動節點, 端口27019位從節點
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1213,
"optime" : {
"ts" : Timestamp(1536820324, 1),
"t" : NumberLong(1)
},{
"_id" : 3,
"name" : "192.168.213.184:27020", #仲裁節點
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1213,
"lastHeartbeat" : ISODate("2018-09-13T06:32:14.152Z"),
(2)模擬主節點故障,關閉主節點服務,登錄另一個標準節點端口 27018 ,查看麟能夠一個標準節點是否被選舉為主節點
abc:PRIMARY> exit
bye
[root@localhost logs]# mongod -f /etc/mongod.conf –shutdown #關閉主節點服務
killing process with pid: 4821
[root@localhost logs]# mongo --port 27018 #指定27018 端口進入數據庫abc:PRIMARY> rs.status() #查看狀態
"members" : [
{
"_id" : 0,
"name" : "192.168.213.184:27017",
"health" : 0, #健康之為 0 ,說明端口27017 已經宕機了
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},{
"_id" : 1,
"name" : "192.168.213.184:27018", #此時另一臺標準節點被選舉為主節點,端口為 27018
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2812,
"optime" : {
"ts" : Timestamp(1536820668, 1),
"t" : NumberLong(2)
},{
"_id" : 2,
"name" : "192.168.213.184:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1552,
"optime" : {
"ts" : Timestamp(1536820668, 1),
"t" : NumberLong(2)
},{
"_id" : 3,
"name" : "192.168.213.184:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1552,其中, health 為 1 代表健康,0 代表宕機。 state 為 1 代表主節點,為 2 代表從節點
(3)將標準節點服務全部關閉,查看被動節點是否會被選舉為主節點
abc:PRIMARY> exit
bye
[root@localhost logs]# mongod -f /etc/mongod2.conf –shutdown #關閉主節點服務
killing process with pid: 4853
[root@localhost logs]# mongo --port 27019 #開啟備用節點服務abc:SECONDARY> rs.status()
"members" : [
{
"_id" : 0,
"name" : "192.168.213.184:27017", #此時兩個標準節點都處于宕機狀態,健康值為 0
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},{
"_id" : 1,
"name" : "192.168.213.184:27018",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},{
"_id" : 2,
"name" : "192.168.213.184:27019", #被動節點并沒有被選舉為主節點,說明被動節點不可能成為活躍節點
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 3102,
"optime" : {
"ts" : Timestamp(1536820928, 1),
"t" : NumberLong(2)
},{
"_id" : 3,
"name" : "192.168.213.184:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1849,
(4)再次啟動標準節點服務,查看主節點能否恢復。
abc:SECONDARY> exit
bye
[root@localhost logs]# mongod -f /etc/mongod.conf #啟動實例1 的服務
about to fork child process, waiting until server is ready for connections.
forked process: 39839
child process started successfully, parent exiting
[root@localhost logs]# mongod -f /etc/mongod2.conf #啟動實例2的服務
about to fork child process, waiting until server is ready for connections.
forked process: 39929
child process started successfully, parent exiting
[root@localhost logs]# mongo{
"_id" : 0,
"name" : "192.168.213.184:27017", #端口27017 恢復為主節點,(與標準節點啟動順序有關,先啟動的為主節點)
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 25,
"optime" : {
"ts" : Timestamp(1536821324, 1),
"t" : NumberLong(3)
},{
"_id" : 1,
"name" : "192.168.213.184:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 14,
"optime" : {
"ts" : Timestamp(1536821324, 1),
"t" : NumberLong(3)
},{
"_id" : 2,
"name" : "192.168.213.184:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 23,
"optime" : {{
"_id" : 3,
"name" : "192.168.213.184:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 23,
由此可以看出:只有標準節點可能被選舉為活躍節點(主 primary),被動節點不可能成為活躍節點,有選舉權。仲裁節點不可能成為活躍節點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。