上一篇我們了解了MongoDB的基本概念與單節點環境搭建,本篇我們來學習如何搭建一個高可用的復制集集群。
1 關於MongoDB復制集
MongoDB復制集的主要意義在於實現服務的高可用,它是MongoDB的一個原生的高可用設計,不需我們額外引入一些組件來實現,因此實現起來相當便利。
主要功能
一是數據寫入時將數據迅速地復制到另一個獨立的節點上;
二是在接受寫入的節點發生故障時自動選舉出一個新的替代節點;
附加功能
數據分發:將數據從一個區域復制到另一個區域,減少另一個區域的度延遲;
讀寫分離:不同類型的壓力分別在不同的節點上執行;
異地容災:在數據中心故障時快速切換到異地;
典型結構
一個典型的MongoDB復制集由3個以上具有投票權的節點組成:
(1)一個主節點(Primary),接受寫入操作和選舉時投票;
(2)兩個(或多個)從節點(Secondary),復制主節點上的新數據和選舉時投票;
如何復制
當一個Mongo的修改操作(CRUD)成功,在主節點時它對數據的操作會被記錄下來,這些記錄被稱為oplog,並傳遞給從節點。從節點通過不斷獲取新進入主節點的oplog,並在自己的數據上進行回放,以此保持和主節點的數據一致。
如何選舉
具有投票權的節點之間兩兩互相發送心跳,當5次心跳未收到時則會判斷節點為失聯。如果失聯的是主節點,從節點會發起選舉,選出新的主節點。如果失聯的是從節點,不會產生新的選舉。
整個選舉過程基於Raft一致性算法實現,選舉成功的必要條件是大多數投票節點存活(這也是為啥大多數需要選舉的中間件集群要保持奇數個節點的原因),整個復制集中可以<=50個,但具有投票權的節點<=7個。
2 實踐准備工作
准備VMware Workstation
跟上一篇一樣,這次我們仍然會通過VMware Workstation啟動幾個虛擬機來完成搭建實踐。
准備三台CentOS 7.x虛擬機
這里模擬的是三個Mongo節點的主從復制集,因此分別命名為mongo-master、mongo-slave1、mongo-slave2。
為了較好的模擬,在三個虛擬機中分別配置一下hosts文件:
vi /etc/hosts
在hosts文件中加入以下內容(IP地址為你配置的虛擬機IP):
192.168.58.100 mongo-master 192.168.58.101 mongo-slave1 192.168.58.102 mongo-slave2
可以驗證一下能否通過主機名互相ping通。
下載Mongo Server到三台虛擬機
下載地址:https://www.mongodb.com/try/download/community
目前Server社區版最新版本為4.4.5:
這里,我們復制到的目錄假設為:/usr/local/mongodb/tgz
復制完成后,分別進行解壓壓縮包,然后將其重命名:
tar -zvxf mongodb-linux-x86_64-rhel70-4.4.5.tgz mv ./mongodb-linux-x86_64-rhel70-4.4.5 /usr/local/mongodb
准備三個Mongo節點的目錄和文件
進入目錄:cd /usr/local/mongodb
創建db目錄:mkdir /usr/local/mongodb/data/db
創建日志目錄:mkdir /usr/local/mongodb/logs
創建日志文件:touch /usr/local/mongodb/logs/mongodb.log
准備三個Mongo節點的配置文件
進入目錄:cd /usr/local/mongodb
創建mongo配置文件:vi mongodb.conf
復制以下內容進入mongodb.conf:
systemLog: destination: file path: /usr/local/mongodb/logs/mongodb.log # log path logAppend: true storage: dbPath: /usr/local/mongodb/data/db # data directory net: bindIp: 0.0.0.0 port: 27017 # port replication: replSetName: localrs processManagement: fork: true
添加三個Mongo節點的環境變量
修改profile文件:
cat >>/etc/profile<<"EOF" >export PATH=$PATH:/usr/local/mongodb/bin >EOF
刷新profile文件:
source /etc/profile
修改.bashrc文件:
cat >>/root/.bashrc<<"EOF" >export PATH="$PATH:/usr/local/mongodb/bin" >EOF
這時可以在任何目錄下輸入mongo命令就可以進入mongo了。
添加三個Mongo節點的開機啟動
進入system目錄:cd /lib/systemd/system
執行以下命令:
cat >>mongodb.service<<"EOF"
在>提示符下復制以下內容:
[Unit] Description=mongodb After=network.target remote-fs.target nss-lookup.target [Service] Type=forking ExecStart=/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/usr/local/mongodb/bin/mongod --shutdown --config /usr/local/mongodb/mongodb.conf PrivateTmp=true [Install] WantedBy=multi-user.target
輸入EOF結束。
然后,設置mongodb.service的執行權限:
chmod +x mongodb.service
最后,設置mongodb.service開機自啟動:
systemctl enable mongodb.service
3 快速配置MongoDB復制集
在主節點配置復制集
進入mongo shell:mongo
>rs.initiate()local
rs:SECONDARY> rs.add("mongo-slave1:27017") # 注意這里master節點還處於SECONDARY角色了
localrs:PRIMARY> rs.add("mongo-slave2:27017") # 注意這里master節點已經被選為PRIMARY角色了
在兩個從節點配置復制集
localrs:SECONDARY>rs.secondaryOk()
測試復制集是否可用
首先,在主節點進入shell並插入一條數據:
localrs:PRIMARY>db.yzjc.insertOne({"name":"cscec-jc-team"})
localrs:PRIMARY> db.yzjc.find().pretty()
{ "_id" : ObjectId("608b74155839b06ac76a938d"), "name" : "cscec-jc-team" }
然后,分別在兩個從節點查詢剛剛在主節點新插入的數據是否已經同步:
localrs:SECONDARY> db.yzjc.find().pretty()
{ "_id" : ObjectId("608b74155839b06ac76a938d"), "name" : "cscec-jc-team" }
可以看到,已經同步到了兩個從節點了。
參考資料
唐建法,《MongoDB高手課》(極客時間)
郭遠威,《MongoDB實戰指南》(圖書)
△推薦訂閱學習