一、主從複製
1、讀寫分離的概念
1、讀寫分離的概念
讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫複製被用來把事務性操作導致的變更同步到集羣中的從數據庫。
讀寫分離的目的是爲了實現高併發場景下的請求分流,避免對數據庫的訪問過於集中,導致性能下降甚至是宕機。
2、主從複製介紹
2、主從複製介紹
在MongoDB的集羣中,會有指定爲master的主節點存在,該節點用於被客戶端進行數據的增刪改操作。同時集羣中還會有被指定爲slave的節點存在,即從節點,該節點主要接收來自於客戶端的讀,檢索操作,並不具備增刪改操作的功能。
在master節點處理完增刪改操作後,會實時同步數據到與其綁定的從節點上,實現主從複製至少要有兩個數據庫實例,並且每個從節點需要知道主節點的地址,如果是在linux中記得開通主從端口的防火牆。
主從複製的優勢在於比較靈活,適用於數據備份,故障後人工進行數據恢復,以及對讀數據的擴展等。
3、主從複製侷限
3、主從複製侷限
(1)MongoDB目前建議使用副本集實現集羣管理,不建議使用簡單的主從複製
(2)主從複製在master宕機後,沒有自動選舉master機制,導致主節點服務一掛,便不能對外提供增刪改操作。
(3)所有增刪改操作都是針對主節點進行操作,可能導致主節點性能下降。
(4)從節點對主節點的數據都是全量拷貝,對主從節點的壓力都是不小的。
4、主從複製簡單配置及實現
4、主從複製簡單配置及實現
設備有限,爲方便簡單的實現,可在一臺機器上模擬主節點和從節點。在C盤創建master目錄,在E盤創建slave目錄,master目錄作爲主節點數據存放的目錄,slave目錄作爲從節點數據存放的目錄。
注意:主節點和從節點要指定不同的端口。
啓動主節點:mongod --dbpath C:\master --port 666 --master
啓動從節點:mongod --dbpath E:\slave --port 888 --slave --source localhost:666
啓動成功後就可以連接主節點進行操作了,而對主節點的操作會同步到從節點,而對從節點進行插入操作時,會報not master的提示並拒絕寫入數據。
配置實現解釋
master:默認爲false,若要設置當前節點爲主節點,需要在服務端啓動添加--master
slave:默認爲false,若要設置當前節點爲從節點,需要在服務端啓動添加--slave
source:默認爲空,用於從節點,指定從節點的複製來源,即主節點所在的地址,格式爲:<host><:port>
only:默認爲空,用於從節點,主動複製默認複製主節點上所有的數據庫,通過設置此項指定需要複製的數據庫名稱
slavedelay:設置從節點同步主節點的延遲時間,用於從節點設置,默認爲0,單位秒。
autoresync:默認爲false,用於從節點設置。是否自動重新同步。設置爲true,如果落後主節點超過10秒,會強制從節點自動重新同步。如果oplogSize太小,此設置可能有問題。如果oplog大小不足以存儲主節點的變化狀態和從節點的狀態變化之間的差異,這種情況下強制重新同步是不必要的。當設置autoresync選項設置爲false,10分鐘內從節點不會進行大於1次的自動重新同步。
什麼是oplog?
主節點的操作會被記錄爲oplog,存儲在系統數據庫local的集合oplog.$main中,這個集合中的每個文檔都代表主節點的一個操作(不包括查詢),從節點定期從主服務器獲取oplog數據,並在本機進行執行,oplog使用的是固定集合,隨着操作的逐漸增加,新的文檔會逐漸覆蓋舊的文檔。
二、副本集
1、副本集概念
1、副本集概念
什麼是副本?可能第一印象想到的是遊戲副本,遊戲副本就是爲了讓每個玩家都有一個獨立的遊戲環境,這種環境的複製就是副本的一種體現。MongoDB也提供了對副本的支持,副本集中有多個副本保證數據庫的容錯性,即使一個副本掛掉了還是會存在很多副本;並且支持副本間的自動選舉,切換,解決了上一篇博文講到的主從複製的故障恢復得人工進行的問題。其實主從複製就是一個單副本,缺少擴展性,容錯性。
2、副本集原理及圖解
2、副本集原理及圖解
應用服務器,也就是客戶端,連接到MongoDB的整個副本集,副本集中有一臺主服務器負責整個副本集的讀寫,副本節點定期同步主節點的數據和oplog,以保證數據的一致性,一旦主節點宕機或掛掉,副本節點會通過心跳機制檢測到,並根據事先副本集創建時設置的節點優先級進行主節點的重新選舉,從而保證高可用。如此,客戶端完全不必關心副本集的健康狀況,MongoDB集羣也可以長期保持高可用。
副本集提供了MongoDB集羣故障的自動回覆機制,擴展性高,容錯性強,是MongoDB官方強烈推薦使用的集羣解決方案。
3、副本集使用說明
3、副本集使用說明
以4個節點爲例,ip,端口,日誌以及數據存放路徑如下
節點1
地址:127.0.0.1:1001 # 在項目中,是實際的機器IP和端口,
如192.168.1.101:27017
安裝路徑:D:\mongodb_cluster\MongoDB1
日誌存放路徑:D:\mongodb_cluster\MongoDB1\log\mongodb.log
數據存放路徑:D:\mongodb_cluster\MongoDB1\data
節點2
地址:127.0.0.1:1002
安裝路徑:D:\mongodb_cluster\MongoDB2
日誌存放路徑:D:\mongodb_cluster\MongoDB2\log\mongodb.log
數據存放路徑:D:\mongodb_cluster\MongoDB2\data
節點3
地址:127.0.0.1:1003
安裝路徑:D:\mongodb_cluster\MongoDB3
日誌存放路徑:D:\mongodb_cluster\MongoDB3\log\mongodb.log
數據存放路徑:D:\mongodb_cluster\MongoDB3\data
節點4
地址:127.0.0.1:1004
安裝路徑:D:\mongodb_cluster\MongoDB4
日誌存放路徑:D:\mongodb_cluster\MongoDB4\log\mongodb.log
數據存放路徑:D:\mongodb_cluster\MongoDB4\data
分別啓動節點命令如下
啓動節點1:
mongod --dbpath D:\mongodb_cluster\MongoDB1\data --logpath D:\mongodb_cluster\MongoDB1\log\mongodb.log --logappend --port 1001 --replSet guanghuan
啓動節點2:
mongod --dbpath D:\mongodb_cluster\MongoDB2\data --logpath D:\mongodb_cluster\MongoDB2\log\mongodb.log --logappend --port 1002 --replSet guanghuan
啓動節點3:
mongod --dbpath D:\mongodb_cluster\MongoDB3\data --logpath D:\mongodb_cluster\MongoDB3\log\mongodb.log --logappend --port 1003 --replSet guanghuan
啓動節點4:
mongod --dbpath D:\mongodb_cluster\MongoDB4\data --logpath D:\mongodb_cluster\MongoDB4\log\mongodb.log --logappend --port 1004 --replSet guanghuan
啓動節點命令解釋
dbpath: 數據存放路徑
logpath:日誌存放路徑
logappend : 日誌拼接聲明
replSet:聲明是副本集,後面格式爲副本集名稱/與之位於同一個副本集的節點地址(副本集要求至少要有兩個節點,一個主,一個從)
--fork:後臺啓動,這裏爲了效果沒有添加此參數
初始化節點(只能初始化一次,執行初始化之前,必須啓動所有節點)
mongo 127.0.0.1:1001
use admin
rs.initiate(
{"_id" : "guanghuan",
"members" : [
{"_id" : 1, "host" : "127.0.0.1:1001", "priority":3},
{"_id" : 2, "host" : "127.0.0.1:1002", "priority":2},
{"_id" : 3, "host" : "127.0.0.1:1003", "priority":1},
{"_id" : 4, "host" : "127.0.0.1:1004", "arbiterOnly" : true}
]
});
初始化節點命令解釋
_id:副本集名稱,與啓動節點中的名稱保持一致
host:副本集成員地址
priority:優先級,即選舉成爲新master的優先級,越大優先級越高
arbiterOnly:仲裁節點
驗證 : rs.status() # 查看副本集的狀態
登錄主節點,即優先級最高的master節點,輸入是否主節點的命令:rs.isMaster()
相關指令:
rs.remove(hostportstr) : 刪除節點hostportstr:127.0.0.1:1003
rs.add(hostportstr) :增加節點
登錄所有副本集成員,設置:rs.slaveOk(),不然副本集不允許讀取數據
修改節點優先級:
cfg = rs.conf()
cfg.members[0].priority=10
rs.reconfig(cfg)
將該主節點關閉,登錄優先級第二的從節點,輸入是否主節點的命令: 發現在主節點宕機後,優先級較高的節點被選舉爲了master節點,繼續負責讀寫的工作,從而持續地提供服務,保持集羣高可用。
4、仲裁者節點及其作用
4、仲裁者節點及其作用
當集羣中的節點數量爲偶數個時,投票選舉機制會根據數據最後操作,更新時間戳,優先級等來判定誰將成爲master節點,如果出現以上條件都符合的情況,且票數相等,此投票環節需要等待若干分鐘,這對於客戶端來說是無法接受的。
仲裁節點的出現打破了這個僵局,仲裁節點並不需要太多系統資源,也並不持有數據本身,而是參與投票並有效協調從節點爭master的撕逼。
集羣中部署多仲裁節點時,需在初始化副本集時,添加屬性arbiterOnly:true。
三、筆記
1、mongodb中 嵌套文檔的訪問
1、mongodb中 嵌套文檔的訪問
{size:{w:18}}
是通過 "size.w" 來進行訪問
2、$field_name
2、mongodb中, 只要字段出現在 : 符號的右邊,必須通過 '$field_name' 來進行訪問
3、心跳包
3、心跳包
機器A 向 機器B 發送心跳包
其實就是機器A 定時向 機器B 發送一個特定的數據包, 告訴機器B, 我機器A還在正常工作
這個 特定的數據包 就叫做心跳包,因爲他是 定時發送的, 就類似人的心跳
4、搭建 副本集 命令
4、搭建 副本集 命令 (先:每個實例配置啓動(下面爲啓動一個的樣例), 後:初始化副本集 rs.initiate(......))
mongod --dbpath D:\mongodb_cluster\MongoDB\data --logpath D:\mongodb_cluster\MongoDB\log\mongodb.log --logappend --bind_ip 192.168.8.254 --port 1809 --replSet guanghuan
rs.initiate(
{"_id" : "guanghuan",
"members" : [
{"_id" : 1, "host" : "192.168.8.254:1809", "priority":30},
{"_id" : 3, "host" : "192.168.8.226:1809", "priority":30},
{"_id" : 4, "host" : "192.168.8.98:1809", "priority":30},
{"_id" : 5, "host" : "192.168.8.227:1809", "priority":30},
{"_id" : 6, "host" : "192.168.8.106:1809", "priority":30},
{"_id" : 7, "host" : "192.168.8.144:1809", "priority":30},
{"_id" : 24, "host" : "192.168.8.254:1004", "arbiterOnly" : true}
]
})