天天看點

單執行個體Mongo更新為副本集

背景

因為是做短信業務的,随着公司業務增加,資料庫壓力也日益增加,目前資料量在70億左右,Mongo隻存儲一周内的資料,資料量将近1億左右。之前想要節省成本,是以一直都是單執行個體。随着接入客戶日益增多,每天短信發送量也開始大幅度增加,最擔心的就是過節假日,一直比較擔心如果Mongo突然挂了,哈 哈!那就是面向死亡程式設計了。

糾結

經過幾次讨論最終決定采用Mongo副本集讀寫分離處理,于是開始了服務改造。

準備

  • 已經部署好Mongo的機器數台伺服器(192.168.0.101、192.168.0.102、192.168.0.103、192.168.0.104),安裝Mongo參考:Linux安裝Mongo
  • 機器說明:兩台Mongo為從庫,一台隻負責投票節點不處理資料節點(192.168.0.104)

更新

秘鑰檔案

通過keyfile身份驗證,副本集中的每個mongod執行個體都将密鑰檔案的内容用作共享密碼,以對部署中的其他成員進行身份驗證。隻有具有正确密鑰檔案的mongod個執行個體可以加入副本集。密鑰檔案的内容長度必須在 6 到 1024 個字元之間,并且副本集的所有成員都必須相同。

openssl rand -base64 756 > /key/mongodb-keyfile
chmod 400 /key/mongodb-keyfile
           

将密鑰檔案複制到承載副本內建員的每個伺服器上。確定運作mongod執行個體的使用者是檔案的所有者,并且可以通路密鑰檔案。

修改每台服務Mongo配置

首先停止單執行個體Mongo(指令:systemctl stop mongod),修改mongo配置檔案 /etc/mongod.conf中的net、security、replication配置資訊

net:
  port: 27017
  bindIp: 0.0.0.0  # 允許所有ip遠端連接配接Mongo

security:
  authorization: enabled # 使用者隻能通路已為其授予特權的資料庫資源和操作。
  keyFile: /key/mongodb-keyfile # 秘鑰檔案路徑

replication:
  replSetName: "S1" # 副本集名稱
  enableMajorityReadConcern: false # 以為有投票節點,禁用該功能以防止存儲高速緩存壓力使部署無法固定。
           

啟動Mongo

使用指令(systemctl start mongo),進入mongo (希望作為主節點的Mongo),執行處理化副本集配置

rs.initiate( {
   _id : "s1",
   members: [
      { _id: 0, host: "192.168.0.101:27017" },
      { _id: 1, host: "192.168.0.102:27017" },
      { _id: 2, host: "192.168.0.103:27017" },
      { _id: 3, host: "192.168.0.104:27017",arbiterOnly:true },
   ]
})
           

檢視副本集配置,更新完成(遠端連接配接檢視)

rs.conf();
           

臨時成員添加副本集中

rs.add( { host: "192.168.0.105:27017", priority: 0, votes: 0 } )
           

注:

當新添加的輔助節點的votes和priority設定大于零時,在其初始同步期間,即使輔助節點不能提供讀取或成為主節點,因為其資料仍不一緻,是以該輔助節點仍會計為有表決權的成員。

這可能導緻大多數投票成員線上但無法選舉主要成員的情況。為避免這種情況,請考慮首先使用priority :0和votes :0添加新的輔助伺服器。然後,一旦成員已轉換為SECONDARY狀态,請使用rs.reconfig()更新其優先級和投票。

如果rs.conf()傳回

192.168.0.105:27017

的配置文檔作為members數組中的第五個元素,以将其優先級更新并投票給

1

,請使用以下操作序列

var cfg = rs.conf();
cfg.members[4].priority = 1
cfg.members[4].votes = 1
rs.reconfig(cfg)
           

異常問題

一、秘鑰檔案讀取授權失敗異常,造成啟動失敗

{"t":{"$date":"2020-10-17T14:38:26.085+08:00"},"s":"I",  "c":"ACCESS",   "id":20254,   "ctx":"main","msg":"Read security file failed","attr":{"error":{"code":30,"codeName":"InvalidPath","errmsg":"Error reading file /key/mongodb-keyfile: Permission denied"}}}
           

解決方案:

原來想着是不是權限太小,于是直接授權 777 權限發現直接報 file Permission too open 錯誤,是以直接擴大權限方案錯誤。

1、預設情況下,MongoDB 使用

mongod

使用者帳戶運作。建立後,将目錄的所有者群組設定為

mongod

sudo chown -R mongod:mongod /key/mongodb-keyfile
           

2、按照官方文檔給出的隻要修改檔案組即可讀取成功,但是不幸的是仍然讀取檔案失敗,通過各種搜尋資料最後在Rad Hat linux官方目錄權限文檔才找到最終解決方案,需要需改SELinux政策配置

chcon system_u:object_r:mongod_var_lib_t:s0 /key/mongodb-keyfile
           

二、讀取秘鑰檔案too open 錯誤

解決方案:

1、因為在 UNIX 系統上,密鑰檔案不得具有組或世界權限。在 Windows 系統上,不檢查密鑰檔案權限。是以隻需開放讀權限,權限不允許過大

chmod 400 /key/mongodb-keyfile
           

參考文檔:

https://docs.mongodb.com/manual/

https://stackoverflow.com/questions/28251531/permission-denied-to-read-file-owned-by-user

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security-enhanced_linux/chap-security-enhanced_linux-selinux_contexts