mongodb副本集介紹、mongodb副本集搭建、 mongodb副本集測試
mongodb副本集介紹
- MongoDB早期版本使用master-slave,一主一從和MySQL主從基本是一致的,但salve在此架構中為只讀,當主庫宕機後,從庫不能自動切換為主.
- 目前已經淘汰master-salve模式,改為副本集,副本集架構也是為了實現MongoDB的高可用,這種模式下有一個主(primary),和多個從(secondary)只讀,支援他們設定權重,當主宕機後,權重最高的從切換為主.
- 在此架構中還可以建立一個仲裁(arbiter)的角色,它只負責裁決,而不儲存資料.
- 在此架構中讀寫資料都是在主上,要想實現負載均衡的目的需要手動指定讀庫的目標server.
MongoDB副本集架構圖
原理很簡單一個primary,secondary至少是一個,也可以是多個secondary,除了多個secondary之外,還可以加一個Arbiter,Arbiter叫做仲裁,當Primary宕機後,Arbiter可以很準確的告知Primary宕掉了,但可能Primary認為自己沒有宕掉,這樣的話就會出現腦裂,為了防止腦裂就增加了Arbiter這個角色,尤其是資料庫堅決不能出現腦裂的狀態,腦裂會導致資料會紊亂,資料一旦紊亂恢復就非常麻煩.
變遷圖
說明:Primary宕機後,其中secondary就成為一個新的Primary,另外一個secondary依然是secondary的角色. 對於MySQL主從來講,即使做一主多從,萬一master宕機後,可以讓從成為新的主,但這過程是需要手動的更改的. 但是在MongoDB副本集架構當中呢,它完全都是自動的,rimary宕機後,其中secondary就成為一個新的Primary,另外一個secondary可以自動識別新的primary.
mongodb副本集搭建
準備三臺機器: 192.168.193.130 (primary)
192.168.193.131 (secondary)
192.168.193.132 (secondary)
三臺機器都需要安裝MongoDB,primary已安裝過,兩臺secondary需要安裝,因步驟一樣,在此不做演示.
編輯三臺機器的配置檔案
[root@aminglinux-130 ~]# vim /etc/mongod.conf
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,192.168.193.130 # Listen to local interface only, comment to listen on all interfaces.
"/etc/mongod.conf" 44L, 784C
說明:做副本集bindIp 要監聽本機IP和內網IP
#replication: //把#去掉,並增兩行
replication:
oplogSizeMB: 20 //前面兩個空格
replSetName;annalinux //定義副本集的名字 前面兩個空格
重啟MongoDB服務:
[root@aminglinux-130 ~]# systemctl restart mongod
啟動從主機
[root@aminglinux-131 ~]# vim /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,192.168.193.131 # Listen to local interface only, comment to listen on all interfaces.
說明:做副本集bindIp 要監聽本機IP和內網IP
#replication: //把#去掉,並增兩行
replication:
oplogSizeMB: 20
replSetName: annalinux //定義副本集的名字
重啟MongoDB服務:
[root@aminglinux-131 ~]# systemctl restart mongod
[root@aminglinux-131 ~]# ps aux |grep mongod
mongod 3111 2.2 3.9 1018232 39316 ? Sl 16:23 0:21 /usr/bin/mongod -f /etc/mongod.conf
root 3282 0.0 0.0 112704 660 pts/0 R+ 16:39 0:00 grep --color=auto mongod
啟動從主機
[root@aminglinux-132 ~]# vim /etc/mongod.conf
#replication: //把#去掉,並增兩行
replication:
oplogSizeMB: 20
replSetName: annalinux //定義副本集的名字
[root@aminglinux-132 ~]# systemctl restart mongod
[root@aminglinux-132 ~]# ps aux |grep mongod
mongod 3246 60.0 3.7 1018232 37532 ? Sl 16:44 0:42 /usr/bin/mongod -f /etc/mongod.conf
root 3292 0.0 0.0 112720 980 pts/0 R+ 16:45 0:00 grep --color=auto mongod
連線MongoDB --Primary機器
[root@aming-130 ~]# mongo
MongoDB shell version v3.4.9
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.9
Server has startup warnings:
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten]
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten]
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten]
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten]
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2017-10-20T17:18:53.740+0800 I CONTROL [initandlisten]
置副本集
說明:在哪臺機器上執行這一步,那麼哪臺機器就會成為primary
> config={_id:"annalinux",members:[{_id:0,host:"192.168.193.130:27017"},{_id:1,host:"192.168.193.131:27017"},{_id:2,host:"192.168.193.132:27017"}]}
{
"_id" : "annalinux",
"members" : [
{
"_id" : 0,
"host" : "192.168.193.130:27017"
},
{
"_id" : 1,
"host" : "192.168.193.131:27017"
},
{
"_id" : 2,
"host" : "192.168.193.132:27017"
}
]
}
>
config={_id:"annalinux" --> annalinux(副本集的名字)
members --> 指定成員
rs.initiate(config) -->初始化
> rs.initiate()?
{ "ok" : 1 }
rs.status() -->檢視副本集狀態
說明:可以看到192.168.193.130 顯示:"stateStr" : "PRIMARY"
192.168.193.131和192.168.193.132 分別顯示: "stateStr" : "SECONDARY"
annalinux:OTHER> rs.status()
{
"set" : "annalinux",
"date" : ISODate("2019-05-14T10:54:40.893Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1557831277, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1557831277, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1557831277, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.193.130:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 319,
"optime" : {
"ts" : Timestamp(1557831277, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-14T10:54:37Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1557831175, 2),
"electionDate" : ISODate("2019-05-14T10:52:55Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
"ok" : 1
}
annalinux:PRIMARY> rs.status()
{
"set" : "annalinux",
"date" : ISODate("2019-05-14T11:05:12.553Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1557831909, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1557831909, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1557831909, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.193.131:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 953,
"optime" : {
"ts" : Timestamp(1557831909, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-14T11:05:09Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1557831527, 2),
"electionDate" : ISODate("2019-05-14T10:58:47Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
"ok" : 1
}
annalinux:OTHER> rs.status()
{
"set" : "annalinux",
"date" : ISODate("2019-05-14T11:06:48.154Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1557832006, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1557832006, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1557832006, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.193.132:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 654,
"optime" : {
"ts" : Timestamp(1557832006, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-14T11:06:46Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1557832004, 2),
"electionDate" : ISODate("2019-05-14T11:06:44Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
"ok" : 1
}