MongoDB--副本集基本信息

副本集的概念

副本集是一組服務器,其中有一個是主服務器(primary),用於處理客戶端請求;還有多個備份服務器(secondary),用於保存主服務器的數據副本。若是主服務器崩潰了,備份服務器會自動將其中一個成員升級爲新的主服務器。mysql

副本集特徵:
  · N 個節點的集羣
  · 任何節點可做爲主節點
  · 全部寫入操做都在主節點上
  · 自動故障轉移
  · 自動恢復
副本集還有如下幾個須要注意的地方:
  1. 最小構成是:primary,secondary,arbiter,通常部署是:primary,2 secondary。
  2. 成員數應該爲奇數,若是爲偶數的狀況下添加arbiter,arbiter不保存數據,只投票。
  3. 最大50 members,可是隻能有 7 voting members,其餘是non-voting members。redis

 

一、數據同步
    Mongo的複製功能是經過oplog實現的oplog包含了主節點的每一次寫操做,是主節點的local數據庫中的一個固定集合,備份節點經過查詢這個集合就能夠知道須要進行復制的操做。每一個備份節點有本身的oplog,這樣每一個成員就能夠看成同步源提供給其餘成員使用。備份節點從當前同步源中獲取須要執行的操做,而後在本身的數據集上執行這些操做,最後將這些操做寫入本身的oplog。sql

    若是備份節點掛了,當它重啓後,會自動從oplog中最後一個操做開始同步,因爲複製操做的過程是先複製數據再寫入oplog,因此備份節點有可能在已經同步過的數據上再次執行復制操做。Mongo是這麼處理的:將oplog中的同一操做執行屢次與只執行一次的效果是同樣mongodb

    因爲oplog大小是固定的,一般它的使用空間的增加速度與系統處理寫請求的速率近乎相同。可是有些例外狀況:若是單次處理可以影響到多個文檔,那麼每一個受影響的文檔都會對應oplog的一條日誌。好比執行db.coll.remove()刪除了1000000個文檔,那麼oplog中就會有1000000條操做日誌,這樣oplog很快就會被填滿。

數據庫

 

二、仲裁節點
  仲裁者惟一的做用就是選舉,不保存數據,也不會爲客戶端提供服務,它只是爲了知足「大部分」的要求安全

  添加仲裁者的兩種方式服務器

    >rs.addArb(「server-5:27017」)性能

    >rs.add({「_id」:4,」host」:」 server-5:27017」,」arbiterOnly」:true})spa

 

 仲裁的缺點操作系統

    好比有三個成員的副本集,其中一個是仲裁節點。當一個數據節點掛了,那麼另外一個數據節點成爲主節點,爲了保證數據安全,就須要添加一個新的備份節點,但因爲仲裁節點無數據,那麼新節點的數據傳輸只能靠當前的主節點完成。那麼它不只要處理應用程序請求,還要數據複製到備份節點,會形成服務器壓力巨大

    因此儘可能配置成奇數個數據成員,而不使用仲裁者

 

 

三、優先級
  優先級表示一個成員渴望成爲主節點的程度,取值範圍0-100,默認1,0表明永遠不能成爲主節點(passive member)

  優先級別高的會優先選舉爲主節點(只要他能獲得大部分的支持,而且數據是最新的)

四、心跳
  每一個成員每隔兩秒都會向其餘成員發送一個心跳請求,用於檢查每一個成員的狀態,知道本身是否符合大多數的條件。

 

五、回滾
  若是主節點執行了一次寫請求後掛了,可是備份節點還沒來得及複製此次操做,那麼新選舉出來的主節點就會漏掉此次寫操做。這時就會執行回滾過程。

 

六、內存管理mmap

   mongodb的全部數據其實是存放在硬盤的,全部要操做的數據經過 mmap的方式映射到 內存某個區域內。
  而後, mongodb就在這塊區域裏面進行數據修改,避免了零碎的硬盤操做。
  至於mmap上的內容flush到硬盤就是操做系統的事情了,因此,若是,mongodb在內存中修改了數據,而後,mmap數據flush到硬盤以前,系統當機了,就會丟失數據了。
 
  mysql,不管數據仍是索引都存放在硬盤中。到要使用的時候才交換到內存中。可以處理遠超過內存總量的數據。
 
  數據量和性能
     當物理內存夠用的時候,redis》mongodb》mysql
 
  mysql墊底是確定的。至於,redis爲何比mongodb快。仍是跟場景和使用業務有關係的。
  大部分情景下,因爲mongodb要兼顧它特有的弱表結構下複雜的查詢,在不少存取過程上作了妥協。
  其實,這裏並不想說redis和mongodb的性能怎樣,只想說明下隨着數據量的增加,redis和mongodb,mysql是怎麼變化的。
 
  當物理內存不夠用的時候
  redis和mongodb都會使用虛擬內存。
  實際上若是redis要開始虛擬內存,那很明顯要麼加內存條,要麼你換個數據庫了。
  可是,mongodb不同,只要,業務上能保證,冷熱數據的讀寫比,使得熱數據在物理內存中,mmap的交換較少。mongodb仍是可以保證性能。有人使用mongodb存儲了上T的數據。
  mysql,mysql根本就不須要擔憂數據量跟內存下的關係。不過,內存的量跟熱數據的關係會極大地影響性能表現。
 
  當物理內存和虛擬內存都不夠用的時候
  估計除了mysql你沒什麼好選擇了。
 
 
  其實,從數據存儲原理來看,我更傾向於將mongodb歸類爲硬盤數據庫,可是使用了mmap做爲加速的手段而已。

       MongoDB應該分配的內存大小最好知足內存大小>索引+熱數據+鏈接佔用內存,經過db.stats()命令可查看到當前數據庫的索引大小狀況
     db.stats()

      下面是公司的MongoDB存儲了14億數據,佔1.4T存儲空間

複製代碼
shard1:SECONDARY> db.stats()
{
    "db" : "database",            // 當前使用的數據庫 
    "collections" : 662,             // 多少張表 
    "objects" : 1405948982,         // 全部表的多少條數據      -- 14.05億
    "avgObjSize" : 1134.649427176014,    // 平均每條數據大小       
    "dataSize" : 1595259207065,      // 總數據大小         -- 1.485TB
    "storageSize" : 768647647232,     // 全部數據佔磁盤的大小    -- 715.85G
    "numExtents" : 0,
    "indexes" : 1098,            // 索引數量
    "indexSize" : 173431967744,      // 索引大小          -- 160G
    "ok" : 1
}
相關文章
相關標籤/搜索