【私貨】MongoDB 副本集的運維部署
今天趁給團隊分享了MongoDB實戰(zhàn),繼續(xù)給大家聊聊MongoDB的副本集配置部署。
副本集介紹
什么是副本集?副本集是MongoDB的復(fù)制系統(tǒng),用于將數(shù)據(jù)同步到各個服務(wù)器的過程。
單節(jié)點在測試環(huán)境還行,但是在線上生產(chǎn)環(huán)境就不合適了,因為如果單節(jié)點出問題了,會導(dǎo)致應(yīng)用宕機。
所以這個時候我們可以MongoDB的復(fù)制功能,使用多節(jié)點進行部署,其中一臺服務(wù)器節(jié)點宕機了,還有其他節(jié)點運行,進行故障轉(zhuǎn)移,讓應(yīng)用不會受到影響,從而更為高可用。
說到故障轉(zhuǎn)移,MongoDB最初支持一種叫「主從模式」(master-slave)這種模式下MongoDB不會做自動故障轉(zhuǎn)移的。這種模式現(xiàn)在已經(jīng)不推薦使用了,這里就不過多介紹了。
由于副本集新增節(jié)點或者刪除節(jié)點都非常方便,建議即使你一開始是單節(jié)點也以副本集的方式啟動,方便后續(xù)進行節(jié)點添加。
成員介紹
副本集成員這里主要介紹仲裁者arbiter, 延遲備份節(jié)點這兩種成員。
說到仲裁者,這里需要說一個副本集成員之間選舉主節(jié)點過程有一個滿足「大多數(shù)」原則 即 n/2 + 1 。仲裁者作用就是「參與選舉」,不保存數(shù)據(jù)。解決在一開始我們應(yīng)用程序量很小的時候,沒有資源,不想保存三分及以上數(shù)據(jù)副本。
- rs.add({"_id": 3, "host": "server-3:27017", "arbiterOnly": true})
這里注意:
最多只能使用一個仲裁者
奇數(shù)節(jié)點不需要仲裁者
盡可能使用奇數(shù)個數(shù)據(jù)節(jié)點,不使用仲裁者
說完仲裁者,我們說一下「延遲備份節(jié)點」,在給團隊內(nèi)部做分享的時候,我們公司的運維大神專門強調(diào)要講這個,這個是有歷史血淚的。
延遲備份節(jié)點主要作用避免有人不小心刪除了主數(shù)據(jù)庫,或者應(yīng)用程序有一個嚴重Bug導(dǎo)致把所有數(shù)據(jù)玩壞了。為了避免這一類問題,設(shè)置一個延遲備份節(jié)點。強烈建議線上配置,這是有血淚史的。
- rs.add( { _id:4, host: "server-4:27020", priority: 0, hidden:true, slaveDelay:7200, votes:0, buildIndexes:true, arbiterOnly:false } )
其實這也算是一個備份方式之一,保底計劃。
副本集初始化
副本集成員啟動之后,配置這里我放在***一節(jié)來說,這里我們直接說副本集啟動后的初始化操作。
成員初始化操作主要有4個步奏:
- 成員在local.me自己創(chuàng)建標志符,刪除本地已存在的數(shù)據(jù),進行數(shù)據(jù)同步
- 將同步源的所有記錄數(shù)據(jù)克隆到本地,這一步是最耗時的
- 將***個oplog同步中操作記錄下來。
- 創(chuàng)建索引,同步創(chuàng)建索引期間的所有操作
通過上面的4個步奏,就完成了副本集初始化。
副本集備份
備份的方式簡單小結(jié)有以下四種方式:
一、 文件系統(tǒng)快照:其中文件系統(tǒng)快照需要文件系統(tǒng)本身支持,mongod開啟日記系統(tǒng),后面我配置會說。
二、 復(fù)制數(shù)據(jù)目錄:就是復(fù)制數(shù)據(jù)目錄所有文件,在備份我們需要防止數(shù)據(jù)文件不能發(fā)生改變,否則將不可用。
保證數(shù)據(jù)不變,可以通過
- db.fsyncLock() 進行鎖定所有數(shù)據(jù)庫,運行之后后續(xù)操作會加入隊列等待。
- cp -R /data/db/* /backup/
- db.fsyncUnlock() # 解鎖數(shù)據(jù)庫能再次進行寫操作
三、mongodump:備份恢復(fù)速度較慢,不推薦
四、延遲備份節(jié)點: 原則上不算備份策略,但是比較重要通過它來延遲防止數(shù)據(jù)誤操作。
副本集部署
***我們終于說到了副本集配置,這里我們配置好mongod.conf配置,replaSetName設(shè)置為test_rs名,配置如下:
- storage:
- dbPath: /test/mongodb/rs1 # 配置路徑
- journal:
- enabled: true # 開啟日記系統(tǒng)
- systemLog:
- destination: file
- logAppend: true
- path: /test/log/mongodb/rs1.log # 日志
- processManagement:
- pidFilePath: /var/run/mongodb/rs1.pid
- net:
- port: 27018
- bindIp: 1.2.3.4 # 綁定固定IP
- replication:
- replSetName: "test_rs" # 選定配置名
- security:
- authorization: enabled
- keyFile: /test/mongodb/key/test_rs.key
除了上面的配置外,我們可以通過配置init.d的啟動腳本,大家可以去github上面進行搜索一下,有很多啟動腳本通過 sudo service mongodb.rs1 start 進行啟動處理,通過多個節(jié)點進行啟動加入到副本集。
由于mongo默認是沒有密碼的,對于數(shù)據(jù)庫的配置,除了配置帳號密碼以外,如果我們是在騰訊云或者阿里云服務(wù)器上,需要配置安全組,只允許內(nèi)網(wǎng)固定幾臺機器IP,固定端口訪問。
配置優(yōu)化
除了MongoDB配置啟動好了,我們還需要對服務(wù)器做一些配置調(diào)整,主要有以下幾點:
- 禁止內(nèi)存過度分配:overcommit_memory=2
- 禁用大內(nèi)存頁面HugePage:
- 修改文件描述符 > 20000 或者***制
- 關(guān)閉定期任務(wù),比如軟件包自動更新,消耗CPU及內(nèi)存資源,造成服務(wù)抖動異常(類似Redis異步任務(wù)hgetall)
其中vercommit_memory設(shè)置1,滿足所有內(nèi)存分配請求(redis部署),設(shè)置2分配虛擬空間不超過swap與一小部分過度分配的和,設(shè)置0,讓內(nèi)核猜測過度分配大小。
禁止大內(nèi)存:如果不能全部存進內(nèi)存,不考慮超過內(nèi)存容量情況,就可以用大內(nèi)存,但是不能全部存進去的話,那么大塊數(shù)據(jù)會導(dǎo)致更多IO,而且「臟數(shù)據(jù)」落地到硬盤可能從KB到MB。
至此我們服務(wù)部署上線結(jié)束,由于個人經(jīng)驗所限,難免有些疏忽遺漏甚至錯誤,歡迎留言指出,非常感謝。