基於 Docker 的 MongoDB 主從叢集
如果對 Docker 不太懂,可以看看我之前的文章。
這篇文章主要講以下三個內容:
- 前序–聊聊資料庫升級方案
- 一主一從
- 一主兩從
- 一主一從一仲裁
本來是想用 MongoDB 的 Docker 最新映象的,但是 最新映象預設綁定了 localhost (詳見官網)才能連線資料庫,當然,我們也可以進行修改。那我這邊為了方便,就直接使用 mongo 3.4 ,因為 3.4 的版本沒有繫結 localhost 省去一部分麻煩。
前序–聊聊資料庫升級方案
在學習叢集之前,我們來聊聊資料庫的升級方案,我個人認為有如下一些階段,如果我的認知有錯誤,也煩請讀者朋友指出。(這裡,我們先避開快取資料庫)
階段一
描述:開發初期,應用程式與資料庫在同一臺伺服器
缺點:
- 應用程式與資料庫爭奪資源
- 資料庫掛掉,應用程式也無法提供服務
- 無法提供資料容災備份
- 讀寫在同一個節點,壓力大
- 吞吐量小,提供服務能力有限
- 無故障恢復功能
階段二
描述:資料庫獨立到一臺伺服器,與應用程式分離
缺點:
- 資料庫掛掉,應用程式也無法提供服務
- 無法提供資料容災備份
- 讀寫在同一個節點,壓力大
- 吞吐量小,提供服務能力有限
- 無故障恢復功能
階段三
描述:資料庫有主從結構,一臺主要,一臺副本
缺點:
- 資料庫掛掉,應用程式也無法提供服務
- 讀寫在同一個節點,壓力大
- 吞吐量小,提供服務能力有限
- 無故障恢復功能
階段四
描述:一主兩(多)從,讀寫分離
缺點:
- 吞吐量小,提供服務能力有限
- 資料庫節點多,經濟成本相對增大
階段五
描述:分片,橫向擴充套件
缺點:
- 資料庫節點多,經濟成本相對增大
一主一從
version: '2'
services:
master:
image: mongo:3.4
volumes:
- /data/mongodbml/master:/data/db
command: mongod --dbpath /data/db --master
slaver:
image: mongo:3.4
volumes:
- /data/mongodbml/slaver:/data/db
command: mongod --dbpath /data/db --slave --source master:27017
links:
- master
不用新建相應檔案目錄,直接執行 yml 檔案即可。
在執行 yml 檔案之後,執行以下初始化操作:
進入 master 的 mongo 命令列:
docker-compose exec master mongo
插入一條資料:
use test
db.test.insert({msg: "this message is from master", ts: new Date()})
進入 slaver 的 mongo 命令列:
docker-compose exec slaver mongo
檢視副本集資訊:
rs.slaveOk()
use test
db.test.find()
rs.slaveOk() 的功能
db.getMongo().setSlaveOk()
This allows the current connection to allow read operations to run on secondary members. See the readPref() method for more fine-grained control over read preference in the mongo shell.
在 slave 中,查詢到了 master 中插入的資訊
嘗試在 slave 中,插入資訊:
db.test.insert({msg: 'this is from slaver', ts: new Date()})
插入失敗,顯示報錯資訊。
優缺點: master-slave 結構,當 master 掛了,slave 不會被選舉為 master,所以這種結構只起到了備份資料的作用
一主兩從
version: '2'
services:
rs1:
image: mongo:3.4
volumes:
- /data/mongodbtest/replset/rs1:/data/db
command: mongod --dbpath /data/db --replSet myset
rs2:
image: mongo:3.4
volumes:
- /data/mongodbtest/replset/rs2:/data/db
command: mongod --dbpath /data/db --replSet myset
rs3:
image: mongo:3.4
volumes:
- /data/mongodbtest/replset/rs3:/data/db
command: mongod --dbpath /data/db --replSet myset
不用新建相應檔案目錄,直接執行 yml 檔案即可。
在執行 yml 檔案之後,執行以下初始化操作:
docker-compose exec rs1 mongo
初始化各個節點:
rs.initiate()
rs.add('rs2:27017')
rs.add('rs3:27017')
檢視配置與副本級狀態
rs.conf()
rs.status()
插入資訊到主節點:
docker-compose exec rs1 mongo
use test
db.test.insert({msg: 'this is from primary', ts: new Date()})
在副本集中檢測資訊是否同步:
docker-compose exec rs2 mongo
rs.slaveOk()
use test
db.test.find()
docker-compose exec rs3 mongo
rs.slaveOk() //副本集預設僅primary可讀寫
use test
db.test.find()
故障測試:
docker-compose stop rs1
分別檢視其它節點的資訊:注意進入 mongo 命令列後的主從識別符號
docker-compose exec rs2 mongo
docker-compose exec rs3 mongo
優缺點:
- 可進行讀寫分離
- 具備故障轉移能力
一主一從一仲裁
version: '2'
services:
master:
image: mongo:3.4
volumes:
- /data/mongodb3node/replset/rs1:/data/db
command: mongod --dbpath /data/db --replSet newset --oplogSize 128
slave:
image: mongo:3.4
volumes:
- /data/mongodb3node/replset/rs2:/data/db
command: mongod --dbpath /data/db --replSet newset --oplogSize 128
myarbiter:
image: mongo:3.4
command: mongod --dbpath /data/db --replSet newset --smallfiles --oplogSize 128
不用新建相應檔案目錄,直接執行 yml 檔案即可。
在執行 yml 檔案之後,執行以下初始化操作:
docker-compose exec rs1 mongo
初始化各個節點:
rs.initiate()
rs.add('slave:27017')
rs.add('myarbiter:27017',true)//設定為仲裁節點
檢視配置與副本級狀態
rs.conf()
rs.status()
插入資訊到主節點:
docker-compose exec rs1 mongo
use test
db.test.insert({msg: 'this is from primary', ts: new Date()})
在副本集中檢測資訊是否同步:
docker-compose exec rs2 mongo
rs.slaveOk()
use test
db.test.find()
docker-compose exec rs3 mongo
rs.slaveOk() //副本集預設僅primary可讀寫
use test
db.test.find()
故障測試:
docker-compose stop master
分別檢視其它節點的資訊:
docker-compose exec slave mongo
可以看到最後一行標註為: PRIMARY 故障轉移成功
docker-compose exec myarbiter mongo
可以看到最後一行標註為: ARBITER
優缺點:
- 具備故障轉移能力
- 仲裁節點起到選舉作用,節省部分資源
下一篇文章來說說 MongoDB 分片,歡迎關注