1. 程式人生 > >MongoDB復制集(實現選舉復制、故障切換、升級oplog大小、認證復制)

MongoDB復制集(實現選舉復制、故障切換、升級oplog大小、認證復制)

text 災難 會同 pre cfg oot log日誌 wire har

什麽是復制集?
  • 復制集(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大小、認證復制)