資料副本
MongoDB中的一組副本是一群mongod程式,這些程式維護同樣的資料集。副本集提供了冗餘和高可用性,是生產環境部署的基礎。
資料冗餘和可用性
通過在不同的伺服器上儲存相同的資料,副本機制保證了一定程度的容錯,即在一個資料庫掛掉後,資料服務仍然可用。
在某些情況下,副本可以提升資料的讀效能,因為使用者可以從不同的資料庫讀取資料。在不同的資料中心維護資料的拷貝,能夠提高分散式應用程式的可用性。也可以維護額外的副本用於其他的目的,比如災難恢復,告警或者是備份。
Mongo中的副本
一個Mongo副本集包括幾個資料軸承節點和一個可選的仲裁者。在這些節點中,有且只有一個主節點,其他的節點都被認為是輔助節點。
主節點接收所有的寫操作。一套副本中,只有主節點能夠確認{ w: "majority"}
;雖然在一些情況下,另外的mongod程式會在短時間內認為自己是主節點。主節點將所有資料的變動記錄在日誌中,比如oplog
從節點複製主節點的oplog,然後根據日誌重放資料集的變動,通過這樣的方式達到和主節點的資料一致。如果主節點掛掉,一個合格的從節點將發起一次選舉將自己選舉為新的主節點。
可以在副本集中新增一個額外的mongod例項作為仲裁者。仲裁者不維護資料集,它的主要功能是維護節點間的心跳和響應其他副本整合員的請求。因為仲裁者不維護資料,因此和一個完整節點相比,佔用的資源會更少。如果副本集中節點數量是偶數,新增一個仲裁者可以在主節點的選舉中新增多數選票的能力。
仲裁者的角色不會變,主節點有可能會降級成從節點,從節點也可能升級為主節點。
非同步複製
從節點非同步從主節點應用操作。在從主節點同步資料後,即使有部分節點掛掉,副本集依然可以保持工作。
自動故障轉移
當一個主節點和副本集中的其他節點有超過10秒中的連線斷開時,一個合格的從節點將發起選舉,將自己提升為主節點。第一個發起選舉並且得到副本集中大多數選票的節點會成為主節點。
故障轉移過程通常在一分鐘內完成。副本集中的其他節點可能需要10到30秒來讓確認主節點不可訪問。在確認後將發起選舉。選舉的過程可能需要10到30秒。
讀操作
預設情況下,使用者會從主節點中讀取資料,不過使用者也可以通過設定傳送讀請求到從節點。非同步制意味著從節點中的資料可能和主節點並不一致。
資料分片
資料分片是將資料分散儲存在多個機器上。MongoDB使用分片技術來支援部署非常大的資料集,並提高系統的吞吐量。
單伺服器會面臨大量資料和高吞吐量的應用程式的挑戰。比如,高頻率的查詢會耗盡伺服器的CPU資源;大於系統記憶體的工作資料集會對磁碟的I/O造成很大壓力。
有兩種方式來應對系統資料的增長:垂直擴充套件和水平擴充套件。
垂直擴充套件包括增加單個伺服器的能力,比如使用更強的CPU,新增更多記憶體,或者增加儲存空間。現有技術的侷限可能讓單臺機器無法應對某個給定的工作負載。另外,雲服務商能夠提供的硬體配置也有一定的上限。因此在實踐中,垂直擴充套件能夠應對的負載有上限。
水平擴充套件包括資料集的劃分,和多臺伺服器分攤負載,水平擴充套件可以通過新增新的機器來提升處理能力。雖然單機的能力可能不是很強,但是每臺機器都負責處理整體負載的一個子集,因此有能力提供比高速大容量伺服器更高的效率。水平擴充套件提升系統的處理能力只需要新增新的伺服器,這比提升高階伺服器效能所需的成本要低。缺點是增加了基礎設施部署和維護的複雜度。
MongoDB通過分片技術支援系統的水平擴充套件。
分片叢集
MongoDB的分片叢集中有以下元件:
- shard:每個shard都包含資料分片的一個子集。每個shard都可以部署為一個副本集
- mongos:mongos作為查詢路由,提供客戶端應用程式和分片叢集之間的介面
- config servers:config servers儲存叢集中的後設資料和配置資料。在Mongo3.4中,config server必須被部署為副本集。
下圖展示了各個元件之間的互動。
Shard Keys
MongoDB使用shard key對collection的資料分片。shard key由一個不可變的欄位或目標collection中每個文件都存在的欄位組成。
需要在對collection分片的時候選擇shard key。shard key之後不能更改。一個分片的collection只能有一個shard key。
要對一個非空collection分片,collection必須有一個由shard key開始的索引。對於空的collection,如果沒有一個合適索引,MongoDB會建立索引。
shard key的選擇會影響叢集的效能,效率和可擴充套件性。shard key可能會成為叢集的瓶頸,即使叢集中的機器效能都很高。
chunks
MongoDB將資料分片到chunk中。依據選擇的shard key,每個chunk大小都有下限和上限。
在叢集中,MongoDB使用分片叢集均衡器遷移各個chunk。均衡器試圖實現在叢集中chunk的均衡。
分片的優點
讀/寫
MongoDB在分片叢集中,將讀和寫的負載分配到各個節點中,允許每個shard處理叢集操作的一個子集。可以通過新增更多的shard橫向擴充套件這種讀寫能力。
對於包括shard key的查詢,mongos可以將查詢定位到特定的shard。
儲存效能
分片技術將資料分配到叢集中的節點上,每個shard包含總資料集合的一個子集。隨著資料集的增長,新增shard能夠增加叢集的儲存容量。
高可用
即使在部分shard不可用的情況下,叢集依然可以繼續執行部分讀/寫操作。在掛掉的shard不可用期間,可用的shard的讀寫不受影響。
在生產環境中,shard應該部署為副本集,以提供資料冗餘和可用性。
分片注意事項
在叢集上實施分片需要仔細地規劃,執行和維護。
仔細選擇shard key,對於確保叢集的效能和效率是必要的。在分片後不能改變shard key,也不能撤銷分片。
分片有一定的操作要求和限制。
如果查詢不包括shard key,mongos會廣播操作,在叢集中的shard中執行查詢。這樣的查詢可能有較長耗時。
分片和非分片collection
一個資料庫可能同時有分片的collection和非分片的collection。分片的collection是分割槽的,分佈在叢集的不同shard中。非分片的collection儲存在主shard中。每個資料庫都有自己的主shard。
分片叢集的連線
必須連線到mongos路由,來與分片叢集中的collection互動。這種互動包括分片collection和非分片collection。客戶端不允許直接連線到單獨的shard來進行讀寫操作。
分片策略
MongoDB支援兩種分片策略。
雜湊分片
雜湊分片是對shard key的值進行雜湊運算後進行分片。每個chunk基於雜湊後的值進行分配。
一個範圍內的shard key可能很接近,但是hash後的結果很可能不在同一個chunk中。基於雜湊的資料分佈會形成更加均衡的資料分佈,特別是在shard key單調變化的情況下。
但是,雜湊分佈意味著對範圍查詢不太可能定位到單個shard,這會導致廣播操作。
範圍分片
範圍分片是將資料基於shard key的值進行切分。每個chunk基於shard key的值進行分配。
shard key某個範圍內的值更可能分配在相同的chunk中,mongos會將請求導向只含有請求資料的shard中。
範圍分片的效率取決於shard key。欠考慮的shard key會導致資料的分佈不均,這會減少資料分片的優勢或者導致效能瓶頸。
分片叢集的區域
在分片叢集中,可以基於shard key建立資料區域。可以把叢集中的多個shard在同個區域中關聯起來。一個shard可以和任意數量的非衝突區域關聯起來。在平衡的叢集中,MongoDB會將區域中的chunk遷移到區域裡關聯的shard中。
每個區域包括一個或多個範圍的shard key。每個區域的覆蓋範圍總是包容它的下邊界和排它的上界。