副本集與分片是mongo數據庫2種集羣搭建方式linux
副本集(Replica Set)是指同一份數據被保存到N個機器上,每一個機器上都是想同的數據,寫操做發生在主庫,從庫同步主庫的OpLog日誌。mongodb
分片(shard)是指一份數據被分離開保存到N個機器上,N個機器上的數據組合起來是一份數據。shell
成員能夠是如下某種角色:數據庫
|
成爲primarywindows |
對客戶端可見網絡 |
參與投票架構 |
延遲同步異步 |
複製數據分佈式 |
Default性能 |
√ |
√ |
√ |
∕ |
√ |
Secondary-Only |
∕ |
√ |
√ |
∕ |
√ |
Hidden |
∕ |
∕ |
√ |
∕ |
√ |
Delayed |
∕ |
√ |
√ |
√ |
√ |
Arbiters |
∕ |
∕ |
√ |
∕ |
∕ |
Non-Voting |
√ |
√ |
∕ |
∕ |
√ |
表:副本集角色屬性
在副本集中,每一個成員都有優先級,它能夠幫助決定選舉出primary。默認狀況下,全部的成員的優先級都爲1。設置優先級爲0不能成爲主節點,可是能夠參與選舉、數據複製。
mongodb節點會向副本集中的其餘節點每兩秒就會發送一次pings包,若是其餘節點在10秒鐘以內沒有返回就標示爲不能訪問。每一個節點內部都會維護一個狀態映射表,代表當前每一個節點是什麼角色、日誌時間戳等關鍵信息。若是是主節點,除了維護映射表外還須要檢查本身可否和集羣中內大部分節點通信,若是不能則把本身降級爲secondary只讀節點。
副本集同步分爲初始化同步和keep複製。初始化同步指全量從主節點同步數據,若是主節點數據量比較大同步時間會比較長。而keep複製指初始化同步事後,節點之間的實時同步通常是增量同步。初始化同步不僅是在第一次纔會被觸發,有如下兩種狀況會觸發:secondary第一次加入,這個是確定的。secondary落後的數據量超過了oplog的大小,這樣也會被全量複製。oplogSize 能夠經過–oplogSize設置大小,對於linux 和windows 64位,oplog size默認爲剩餘磁盤空間的5%。
secondary不會從delayed和hidden成員上覆制數據。若是同步操做30秒都沒有反應,則會從新選擇一個節點進行同步。
副本集可以自動進行故障切換恢復。若是primary掉線或者無反應且多數的副本集成員可以相互鏈接,則選出一個新的primary。
在多數狀況下,當primary宕機、不可用或者是不適合作primary時,在沒有管理者干預的幾秒後會進行故障切換。若是MongoDB部署沒有如預期那樣進行故障切換,則可能出現了問題:剩餘的成員個數少於副本集的一半;沒有成員有資格成爲primary。
全部的Secondary都宕機、或則副本集中只剩下一個節點,則該節點只能爲Secondary節點,也就意味着整個集羣不能進行寫操做(若是應用程序沒有設置相應的ReadReference也可能不能進行讀取操做),當其餘的恢復時,以前的primary節點仍然是primary節點。
當某個節點宕機後從新啓動該節點會有一段的時間(時間長短視集羣的數據量和宕機時間而定)致使整個集羣中全部節點都成爲secondary而沒法進行寫操做(若是應用程序沒有設置相應的ReadReference也可能不能進行讀取操做)。
副本集部署的架構對其容量和性能都有很大影響。大多數產品部署成包含3個優先級爲1 的成員就足夠了。
如圖:
當primary服務異常後,由secondary節點選舉出新的primary節點。
當開發一個副本集架構時要注意下面的因素:
a) 確保副本集的成員總能選出一個primary。運行奇數個成員或者運行一個仲裁者(arbiter)+偶數個成員。
b) 分佈在不一樣地理位置的成員,知道「羣體」的成員在任意網絡分區中的狀況。試圖確保在主數據中心的成員中選舉出primary。
c) 考慮副本集中包含hidden或者delayed成員用於支持專用功能,如備份、reporting和測試。
d) 考慮保留一或者兩個位於其餘數據中心的成員,同時經過配置確保其不會成爲primary。
e) 使用replica set tags建立定製的寫規則以確保應用可以控制寫操做成功的門限值。使用寫規則確保操做在返回成功以前將操做傳遞給指定的數據中心或不一樣功能的機器。
不存在一個理想的副本集架構能夠知足任意部署環境。
最小的副本集推薦架構爲三成員集合,其中一個爲primary,另外兩個爲secondary,secondary在必定狀況下能夠成爲primary。
若是副本集中的成員多於三個,則須要遵守下面的架構條件:
a) 集合中有奇數個參與投票的成員。若是有偶數個投票成員,則部署一個仲裁者將個數變爲奇數。
b) 集合中同一時刻最多支持12個成員,可是隻有7個成員能夠參與投票,3.0版本後成員能夠多達50個成員,可是隻有7個成員能夠參與投票。
c) 若是不想讓某些成員在故障切換時成爲primary,則將它們的優先級設爲0。
d) 集合的多數成員運行在主要的數據中心。
圖:基於地理上的分佈式副本集
若是primary掉線,則副本集選出一個新的primary;若是主數據中心和備數據中心鏈接失敗,備數據中心的secondary不能成爲primary。若是主數據中心失敗,則須要人爲的從備數據中心恢復數據。
值得注意的是,這種架構下,必須注意在主數據中心要保持奇數個參與投票的成員,上圖中則須要在主數據中心添加一個仲裁者。
Mongodb默認是primary節點負責全部的讀寫操做,讀操做能夠經過配置從secondary節點進讀取,可是寫操做只能經過primary節點進行。
要在副本集上實現讀寫分離,咱們須要實現如下兩步:
a) 在副本節點上設置setSlaveOk;
b) 應用客戶端設置ReadReference(讀偏好)
設置setSlaveOk方法:
a) 進入shell,執行語句rs. setSlaveOk()
b) 永久設置,修改.mongorc.js,添加rs.slaveOk()。
ReadReference(讀偏好)描述了MongoDB客戶端是怎樣路由讀請求到副本集中的成員,模式讀偏好爲主節點模式。
缺點:除了主節點模式,其餘模式返回的多是過時的數據,由於在異步複製時,從節點中的數據不能反映最近的寫入操做;全部的從節點擁有與主節點同樣的寫入負載,讀的加入會增長其負載。
優勢:非主節點模式在故障切換時保持可用性;當超過半數節點故障時,剩餘節點均爲secondary節點。非主節點模式仍然能夠提供讀服務,主節點模式時將不會提供任何服務。
MongDB驅動支持5中讀偏好模式。
讀偏好模式 |
描述 |
primary |
默認模式,全部的讀操做都從當前副本集主節點 |
primaryPreferred |
多數狀況下,從主節點讀取數據,可是若是主節點不可用了,會從從節點讀取 |
secondary |
全部讀操做都從副本集的從節點讀取 |
secondaryPreferred |
多數狀況下, 從從節點進行讀操做,可是若是從節點都不可用了,從主節點讀取 |
nearest |
從副本集中延遲最低的成員讀取,不考慮成員的類型 |
MongoDB驅動容許客戶端應用對於每一個鏈接、每一個collection或者每一個操做進行讀偏好設置,配置多個時執行就近原則。
移除節點
rs.remove('ip:port');
添加節點
rs.add('ip:port')
從新加載配置
rs.reconfig({配置信息})
查詢副本集狀態
rs.status()
查詢副本集配置信息
rs.config()
添加仲裁者節點
rs.addArb('ip:port')