MongoDB復制集(實現選舉復制、故障切換、升級oplog大小、認證復制)
- 復制集(replica sets)是額外的數據副本,是跨多個服務器同步數據的過程,復制集提供了冗余並增加了數據可用性,通過復制集可以對硬件故障和中斷服務進行恢復。
復制集的優勢
- 讓數據更安全。
- 高數據可用性。
- 災難恢復。
- 無停機維護(如備份、索引重建、故障轉移)
- 讀縮放(額外的副本讀取)
- 副本集對應用程序是透明的。
復制集概述
- MongoDB復制集是額外的數據副本,復制集提供了冗余和增加數據可用性。
- MongoDB的復制集至少需要兩個節點,其中主節點負責處理客戶端請求,從節點負責復制主節點上的數據。
- MongoDB復制集可以實現群集的高可用,當主節點出現故障時會自動切換。
- 復制是基於操作日誌oplog,相當於MySQL中的二進制日誌,只記錄發生改變的記錄。復制是將主節點的oplog日誌同步並應用到其他節點的過程。
- 節點類型分為標準節點、被動節點、仲裁節點。只有標準節點可能被選舉為活躍(主)節點。
- 盡量保證主節點的oplog足夠大,能夠存放相當長時間的操作記錄。
復制集服務配置
1、創建多實例
mkdir -p /data/mongodb/mongodb{2,3,4} //創建數據目錄
mkdir logs
touch logs/mongodb{2,3,4}.log //創建日誌文件
cd logs/chmod 777 *.log //賦予權限
- 修改多實例配置文件
vim /etc/mongod2.conf
# where to write logging data. systemLog: destination: file logAppend: true path: /data/mongodb/logs/mongodb2.log //日誌文件存放位置 # Where and how to store data. storage: dbPath: /data/mongodb/mongodb2 //數據文件存放位置 journal: enabled: true # engine: # mmapv1: # wiredTiger: # how the process runs processManagement: fork: true # fork and run in background pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile timeZoneInfo: /usr/share/zoneinfo # network interfaces net: port: 27018 //監聽端口及IP地址 bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces. #security: #operationProfiling: replication: replSetName: abc //打開主從復制集功能,每個節點都要配置相同名稱
2、配置三個節點的復制集
- 如上創建多實例完成後,修改完成配置文件後,依次重啟每個服務。
mongod -f /etc/mongod.conf --shutdown
mongod -f /etc/mongod.conf
mongod -f /etc/mongod2.conf
mongod -f /etc/mongod3.conf
mongod -f /etc/mongod4.conf
- 進入主節點配置復制集
mongo
> show dbs //查看數據庫
> rs.status() //查看復制集狀態
> cfg={"_id":"abc","members":[{"_id":0,"host":"192.168.144.112:27017"},{"_id":1,"host":"192.168.144.112:27018"},{"_id":2,"host":"192.168.144.112:27019"}]} //配置復制集節點IP
> rs.initiate(cfg) //初始化配置時保證從節點沒有數據
> rs.status() //此時再查看復制集狀態
- 當能夠看到如圖狀態,可以看到各節點狀態代表復制集配置完成。
3、復制集的節點添加和刪除
abc:PRIMARY> rs.add("192.168.144.112:27020") //添加節點
abc:PRIMARY> rs.remove("192.168.144.112:27020") //刪除節點
> rs.status()
4、故障轉移切換
自動切換
ps aux | grep mongod
- 模擬故障,復制集完成自動切換
kill -9 46374
手動切換
abc:PRIMARY> rs.freeze(30) //暫停30s不參與選舉
abc:PRIMARY> rs.stepDown(60,30) //交出主節點位置,維持從節點狀態不少於60秒,等待30秒使主節點和從節點日誌同步
MongoDB復制選舉
1、復制原理
- 復制是基於操作日誌oplog,相當於MySQL中的二進制日誌,只記錄發生改變的記錄,復制是將主節點的oplog日誌同步並應用到其他從節點的過程。
2、選舉的原理
-
節點類型分為:標準(host)節點、被動(passive)和仲裁(arbiter)節點。
- (1)只有標準節點可以被選舉為活躍(primary)節點,有選舉權,被動節點有完整副本,不可能成為活躍節點,有選舉權,仲裁節點不復制數據,不可能成為活躍節點,只有選舉權。
- 標準節點與被動節點的區別:priority優先級值高者是標準節點,低著則為被動節點。
- 選舉規則是票數高者獲勝,priority是優先權為0~100的值,相當於額外增加的0~100的票數。
復制選舉配置
- 如上一小節,打開配置文件中復制功能:
replication:
replSetName: abc
選舉節點設置
mongo //進入數據庫
cfg={"_id":"abc","members":[{"_id":0,"host":"192.168.144.112:27017","priority":100},{"_id":1,"host":"192.168.144.112:27018","priority":100},{"_id":2,"host":"192.168.144.112:27019","priority":0},{"_id":3,"host":"192.168.144.112:27020","arbiterOnly":true}]}
//設置節點IP端口以及節點類型
> rs.initiate(cfg) //初始化數據庫
> rs.isMaster() //查看狀態
- 在主節點所有的修改操作將會被記錄在oplog日誌中,下面將模擬修改操作,以及查看oplog日誌記錄。
abc:PRIMARY> use kgc //創建數據庫
abc:PRIMARY> db.t1.insert({"id":1,"name":"tom"}) //創建集合t1並插入數據
abc:PRIMARY> db.t1.insert({"id":2,"name":"jerry"})
abc:PRIMARY> db.t1.find() //查看集合數據
abc:PRIMARY> db.t1.update({"id":2},{$set:{"name":"jack"}}) //修改集合數據
abc:PRIMARY> db.t1.remove({"id":1}) //刪除數據
abc:PRIMARY> use local //進入oplog所在數據庫
abc:PRIMARY> show collections //查看所有集合
oplog.rs //oplog集合
abc:PRIMARY> db.oplog.rs.find()
//查看日誌記錄所有操作,此時從節點會從oplog中同步數據
模擬標準節點故障
- 當標準節點1選舉為primary時,為了模擬故障,直接選擇關閉節點1
mongod -f /etc/mongod.conf --shutdown
- 進入節點2,查看節點2狀態
- 此時會選舉第二個標準節點為主節點
mongo --port 27018
- 當繼續模擬標準節點2故障時,此時兩個標準節點都不能工作,此時進入被動節點三,發現被動節點三不能成為主節點
mongo --port 27019
允許從節點讀取數據
-
在標準節點上寫入數據,其他節點上也會同步復制,如何從從節點上讀取數據?
- 進入從節點數據庫
[root@localhost]# mongo --port 27018
abc:SECONDARY> show dbs //此時從節點不允許讀取數據
abc:SECONDARY> rs.slaveOk() //允許默認從節點讀取數據
abc:SECONDARY> show dbs //再次查看時就可以了
查看復制狀態信息
abc:SECONDARY> rs.help() //查看命令幫助手冊
abc:SECONDARY> rs.printReplicationInfo()
configured oplog size: 990MB
log length start to end: 1544secs (0.43hrs)
oplog first event time: Mon Jul 16 2018 05:49:12 GMT+0800 (CST)
oplog last event time: Mon Jul 16 2018 06:14:56 GMT+0800 (CST)
now: Mon Jul 16 2018 06:14:59 GMT+0800 (CST)
abc:SECONDARY> rs.printSlaveReplicationInfo()
source: 192.168.235.200:27018
syncedTo: Mon Jul 16 2018 06:16:16 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
source: 192.168.235.200:27019
syncedTo: Mon Jul 16 2018 06:16:16 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
abc:ARBITER> rs.printReplicationInfo()
cannot provide replication status from an arbiter.
//會發現仲裁節點並不具備數據復制
更改oplog日誌大小
- oplog即operation log的簡寫,存儲在local數據庫中。oplog中新操作會自動替換舊的操作,以保證oplog不會超過預設的大小。默認情況下,oplog大小會占用64位的實例5%的磁盤空間。
- 在MongoDB復制的過程中,主節點應用業務操作修改到數據庫中,然後記錄這些操作到oplog中,從節點復制這些oplog,然後應用這些修改、這些操作是異步的,如果從節點的操作已經被主節點落下很遠,oplog日誌在從節點上還沒執行完,oplog可能已經輪滾一圈了,從節點跟不上同步,復制就會停下,從節點需要重新做完整的同步,為了避免這種情況,盡量保證主節點的oplog足夠大,能夠存放相當長時間的操作記錄。
查看當前oplog日誌文件大小
abc:PRIMARY> db.printReplicationInfo()
configured oplog size: 1613.301513671875MB //默認大小
log length start to end: 18650secs (5.18hrs)
oplog first event time: Tue Jul 17 2018 11:08:30 GMT+0800 (CST)
oplog last event time: Tue Jul 17 2018 16:19:20 GMT+0800 (CST)
now: Tue Jul 17 2018 16:19:21 GMT+0800 (CST)
離線升級,更改oplog日誌大小
- 針對於主節點服務器oplog日誌大小,如果主節點服務器存在於復制集當中,我們需要先將主節點服務關閉,然後再在配置文件中關閉replication復制相關選項,並且修改端口號,因為如果端口號不改,當服務啟動時,還是會被加入到復制集隊列。將其服務作為單實例啟動。
mongo
abc:PRIMARY> use admin
switched to db admin
abc:PRIMARY> db.shutdownServer()
也可以采用mongod -f /etc/mongod.conf --shutdown 方式關閉服務
vim /etc/mongod.conf
- 註銷replication:相關啟動參數,並修改port端口號27027
...
# network interfaces
net:
port: 27027 //修改端口
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
#replication: //註釋復制功能
# replSetName: abc
...
- 主節點的單實例啟動
mongo -f /etc/mongod.conf
- 備份當前oplog日誌
mongodump --port 27027 --db local --collection ‘oplog.rs‘ //全備份當前節點oplog記錄
- 進入當前節點MongoDB
mongo --port 27027
> use local //進入local數據庫
> db.oplog.rs.drop() //刪除oplog原有集合
> db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } ) //重建oplog,並指定大小
> use admin
> db.shutdownServer() //關閉服務
- 把配置文件修改回來
...
# network interfaces
net:
port: 27017 //端口修改回原有端口
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //取消註釋復制功能
replSetName: abc
oplogSizeMB:2048 //添加指定oplog日誌大小
...
- 啟動節點服務
mongod -f /etc/mongod.conf
mongo --port 27017
abc:SECONDARY> db.printReplicationInfo()
configured oplog size: 2048MB //oplog日誌大小已經改變
log length start to end: 30secs (0.01hrs)
oplog first event time: Tue Jul 17 2018 17:33:18 GMT+0800 (CST)
oplog last event time: Tue Jul 17 2018 17:33:48 GMT+0800 (CST)
now: Tue Jul 17 2018 17:33:54 GMT+0800 (CST)
abc:SECONDARY>
部署認證復制
mongo
-
進入primary
kgcrs:PRIMARY> use admin kgcrs:PRIMARY> db.createUser({"user":"root","pwd":"123","roles":["root"]}) //創建管理用戶,並且使用管理用戶認證
- 在每個實例配置文件中打開認證功能
[root@localhost]# vim /etc/mongod.conf
[root@localhost]# vim /etc/mongod2.conf
[root@localhost]# vim /etc/mongod3.conf
[root@localhost]# vim /etc/mongod4.conf
...
security:
keyFile: /usr/bin/kgcrskey1
clusterAuthMode: keyFile
...
cd /usr/bin/
-
創建認證文件,並且輸入統一認證密匙
[root@localhost bin]# echo "kgcrs key"> kgcrskey1 [root@localhost bin]# echo "kgcrs key"> kgcrskey2 [root@localhost bin]# echo "kgcrs key"> kgcrskey3 [root@localhost bin]# echo "kgcrs key"> kgcrskey4 [root@localhost bin]# chmod 600 kgcrskey{1..4} //設置權限,只有屬主可以查看
- 重啟四個實例
進入primary
kgcrs:PRIMARY> show dbs //無法查看數據庫
kgcrs:PRIMARY> rs.status() ///無法查看復制集
kgcrs:PRIMARY> use admin //身份登錄驗證
kgcrs:PRIMARY> db.auth("root","123")
kgcrs:PRIMARY> rs.status() //可以查看數據庫
kgcrs:PRIMARY> show dbs //可以查看復制集
MongoDB復制集(實現選舉復制、故障切換、升級oplog大小、認證復制)