MongoDB副本集(二)

二、複製過程

    副本集成員不斷複製數據。首先,一個成員使用初始的複製來捕捉數據集,然後持續地記錄和應用每一個數據集上的操作。每一個成員記錄自己的Oplog。
    · 副本集Oplog
    · 副本集數據複製

1、副本集Oplog

    Oplog(operation log)是一個特殊的封裝集合,是對存儲在數據庫中的數據的所有修改操作進行一個滾動的記錄。MongoDB應用數據庫操作到primary,並將操作信息記錄到primary的Oplog中。secondary成員然後通過複製進程,複製和應用這些操作。所有的包含Oplog副本的副本集成員,被記錄在local.Oplog.rs集合中,來允許他們維護數據庫的當前狀態。
    爲了方便複製,所有的副本集成員發送心跳(pings)到其他所有的成員,任何成員可以導入其他成員的Oplog。
    無論是否應用一次或者多次到目標數據集,Oplog中的每一次操作產生相同的結果,也就是,Oplog中的每一個操作都是等冪的。合適的副本集操作,Oplog中的條目一定是等冪的:
    · 最初的sync
    · 隨後的rollback和追趕
    · 分片塊遷移

a.Oplog的大小

    當你第一次使用副本集的成員時,MongoDB創建一個默認大小的Oplog,大小取決於操作系統。
    在多數情況下,默認的Oplog大小是充足的。例如,如果一個Oplog佔用空閒磁盤5%的空間,並會在24小時的操作中填滿,這時secondary會停止複製Oplog多達24小時,而不至於讓持續地複製導致未應用的Oplog變得陳舊。然而,大多數副本集設置擁有更低的操作容量,他們的Oplogs可以承受更多的操作數量。
    在MongoD創建Oplog前,你可以通過OplogSizeMB選項指定大小。然而,在你第一次啓動了一個副本集成員後,你只能通過change the size of the Oplog過程來修改Oplog的大小。
    默認的Oplog的大小如下:
    · 對於64位的linux、solaris、freeBsd和windows系統,MongoDB分配5%的空閒磁盤空間,但是經常會分配至少1G,最多不超過50G的空間。
    · 對於64位的OS X系統,MongoDB分配183M的空間給Oplog
    · 對於32位的系統,MongoDB分配大約48M的空間給Oplog
    工作負荷可能會要求需要更大的Oplog
    如果你可以預測你的副本集的工作負荷,類似於以下模型,這時你可能想創建一個比默認大小更大的Oplog。相反,如果你的應用是read主導和少許的寫操作,一個更小的Oplog可能更加合適。以下的工作負荷可能需要更大的Oplog:
    · 一次性更新多個文檔:Oplog必須將多更新轉換爲單更新操作來保證等冪。這就會用到大量的Oplog空間而不是相應的數據大小增長或磁盤佔用。
    · 刪除和插入同樣數量的數據:如果你粗略地刪除你插入的數據,數據庫不會再磁盤使用上不會明顯地增長,但是Oplog會變得相當大。
    · 大數量的原位置更新:如果工作流的原位更新並沒有增長文檔的大小,數據庫記錄了大量的操作,但是並不會修改磁盤上的文檔數量。

b.Oplog狀態

    想查詢Oplog的狀態,包括大小和操作的時間分佈,使用rs.printReplicationInfo()方法。
    在各種異常的情況下,更新到一個secondary的Oplog可能會延遲於預期的時間。在secondary成員上使用db.getReplicationInfo(),會輸出副本集狀態來評估副本集的當前狀態並確定是否有任何非故意的複製延遲。

2.副本集數據複製

    爲了維護最新的共享數據集的副本,副本集的成員從其他成員處複製或複製數據。MongoDB使用2種數據複製的表格:初始複製來完全填充新成員的數據集,複製來應用不斷變化到全部的數據集。

a.初始化複製

    初始化複製,將副本集中一個成員的所有數據複製到另一個成員。一個成員在沒有任何數據的時候(例如,新加入的成員,或者已經刪除、遺失了歷史數據的成員),會採用初始化複製。  
    當採用初始化複製時,MongoDB將執行:
    · 複製所有的數據庫。先查詢來源的每一個數據庫的所有集合,然後將所有數據插入到自身的數據庫集合中。此時,會建立_id索引。克隆進程僅僅複製可用數據,忽略不可用文檔。
    · 應用所有的Oplog更改到副本集。從來源處獲取Oplog,然後應用這些Oplog,從而更新自身數據來反射副本集的最新狀態。
    · 在集合上建立索引。
    當MongoD完成以上工作時,此成員可以可以轉變爲正常狀態。

b.複製

    成員在初始化複製後,會持續地複製數據。這個過程保證了成員可以將數據更新到最新。多數情況下,secondary從primary處複製。基於ping和其他成員的狀態,必要時secondary會自動的修改他們的複製源。
    當一個成員從另一個成員進行復制時,兩者在索引設置上必須一致。
    注:從version2.2開始,secondary將避免從延遲成員、隱藏成員出複製數據。
    有效性和持久性:在一個副本集中,最多有一個primary,並且只有primary可以接收write操作。secondary從primary處異步地應用操作來提供最終的一致性。日誌提供了單實例的write持久性。沒有日誌,若MongoDb實例不幸終止,數據庫將處於不可用狀態。在MongoDb中,客戶端可以在數據變得持久性前查看write結果(儘管隨後可能會被rollback)
    多線程複製:MongoDb通過多線程來提供了批量寫操作,提高併發量(每一次批量寫操作,稱爲一個批次)。MongoDb通過namespace或者文檔id來對批次分組,同時使用不同的線程應用這些不同的批次。MongoDb經常對於一個文檔按照write順序來應用這些write操作。應用一個批次時,MongoDb會鎖定所有的write操作。因此,secondary的read查詢永遠不會返回不存在於primary中的數據。
    預讀取索引來提升複製能力:使用MMAPv1存儲引擎,MongoDb加載被影響數據和索引到內存中,來提升應用Oplog的性能。預讀取,最小化了MongoDb應用Oplog時,持有write鎖的時間。默認情況下,secondary會預讀取所有的索引。選擇性地,你可以關閉預讀取,或僅僅預讀取_id索引字段,通過secondaryIndexPrefetch設置來查看更多的信息。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章