摘要:并依賴于提供的機制提供高數據可靠性,目前支持單機事務。源通知目標開始同步數據源收到發送的命令后,會向目標發送的命令,通知目標開始遷移數據真正的數據遷移由目標主動發起。源收到的結果,整個數據遷移的步驟完成。
本文分兩部分,分布式和單機。單個db的存儲引擎,物理和數據存儲簡介,事務實現等。分布式架構,分布式涉及的復制集,分片等可靠性和擴展性保障。
第一部分 單機存儲引擎介紹mondod 引擎概述wiredTiger(簡稱WT)支持行存儲、列存儲以及LSM等3種存儲形式,Mongodb使用時,只是將其作為普通的KV存儲引擎來使用,mongodb的每個集合對應一個WT的table,table里包含多個Key-value pairs,以B樹形式存儲。mongodb的集合和索引都對應一個wiredTiger的table。并依賴于wiredTiger提供的checkpoint + write ahead log機制提供高數據可靠性,目前支持單機事務。
按照Mongodb默認的配置,?WiredTiger的寫操作會先寫入Cache,并持久化到WAL(Write ahead log journal),每60s或log文件達到2GB時會做一次Checkpoint,將當前的數據持久化,產生一個新的快照。Wiredtiger連接初始化時,首先將數據恢復至最新的快照狀態,然后根據WAL恢復數據,以保證存儲可靠性。
Wiredtiger的索引采用Btree的方式組織
Wiredtiger采用Copy on write[ps:存儲的COW意在W的時候C一份,不在原來上修改。linux的意在W的時候才C一份,不更改只會存在一份]的方式管理修改操作(insert、update、delete),保證一致性,并且不像InnoDB一樣,需要一個DoubleWriteBuffer保證非disk block 512B寫時對原有頁可能發生conrrupt。修改操作會先緩存在cache里,持久化時,修改操作不會在原來的leaf page上進行,而是寫入新分配的page,每次checkpoint都會產生一個新的root page。
內存結構:B樹索引頁和數據頁(B樹做了改版,中間節點不放數據,要加update和insert占內存),新插入跳表(有序)更新list(會變更,無需有序),copy on write,wal
物理結構:
ACID
寫入:寫入頁的跳表,不改變原值
更新:寫入更新數組中
讀取:若有update合并
ACID:隔離用的未提交快照。注意這個快照只是讀用的。寫還是到最新頁。
關于快照,緩存,數據
每個事務有自己的快照(可能是舊的page_root),新的事務會獲取當前最新page_root(可能還未做checkpoint,因此繼續用舊的,加入寫入跳表和更新數組),checkpoint對最新的做持久化和生成新page_root到磁盤,按需讀取到內存。新建連接會先進行磁盤的數據的數據恢復:最新快照+WAL,按需讀入內存。快照也是通過事務id判斷update和Insert是否可見
journal(wal):并發,預先分配slots,申請slot用CAS,buffer和lsn, 刷盤。傳統的WAL使用互斥體來協調多線程的寫入,這在單核架構上可以很好地工作,多核只有一個鎖浪費,journal的多線程申請slots,并行復制
做checkpoint時,將更新和寫入到新的頁中,生成新的page_root快照。
cache 驅逐:略
數據清理:
compact 加的是DB級別的互斥寫鎖,同一個DB上的讀寫都會被阻塞
compact基本不需要額外的空間,wiredtiger compact的原理是將數據不斷往前面的空洞挪動,并不需要把數據存儲到臨時的位置(額外的存儲空間)。
運行中內存占用
存儲引擎cache,集合,索引元數據,新寫入數據
MongoDB Driver(client) 會跟 mongod 進程建立 tcp 連接,一個連接一個線程的模型。并在連接上發送數據庫請求,接受應答,tcp 協議棧除了為連接維護socket元數據為,每個連接會有一個read buffer及write buffer,用戶收發網絡包,buffer的大小通過如下sysctl系統參數配置,分別是buffer的最小值、默認值以及最大值。500個類似的連接就會占用掉 1GB 的內存 ,ss -m
其他并發大時排序等
主備節點差異,備節點buffer存儲oplog
分片
balancer+route
config
分片:范圍,hash
遷移步驟:
集合分片開啟后,默認會創建一個新的chunk,shard key取值[minKey, maxKey]內的文檔(即所有的文檔)都會存儲到這個chunk。當使用Hash分片策略時,可以預先創建多個chunk,以減少chunk的遷移。
一個 Sharded Cluster 里可能有很多個 mongos(可以理解一個庫一個),如果所有的 mongos 的 Balancer 同時去觸發遷移,整個集群就亂了,為了不出亂子,同一時刻只能讓一個 Balancer 去做負載均衡。
Balancer 在開始負載均衡前,會先搶鎖(config.locks集合下的一個特殊文檔),搶到鎖的 Balancer 繼續干活,沒搶到鎖的則繼續等待,一段時間后再嘗試搶鎖。
Step1: mongos 發送 moveChunk 給源 shard mongos 接受到用戶發送的遷移 chunk 命令,或者因負載均衡策略需要遷移 chunk,會構建一個 moveChunk 的命令,并發送給源 shard。 Step2:源 shard 通知目標 shard 開始同步 chunk數據 源 shard 收到 mongos 發送的 moveChunk 命令后,會向目標 shard 發送 _recvChunkStart 的命令,通知目標 shard 開始遷移數據(真正的數據遷移由目標shard 主動發起)。接下來,源 shard 會記錄該 chunk 在遷移過程中的所有增量修改操作。 Step3: 目標 shard 同步 chunk 數據到本地 目標 shard 接受到 _recvChunkStart 命令后,就會啟動多帶帶的線程來讀取 chunk 數據并寫到本地,主要步驟包括: 目標 shard 創建集合及索引(如果有必要) 如果遷移的集合在目標 shard 上沒有任何 chunk,則需要先在目標 shard 上創建集合,并創建跟源 shard 上集合相同的索引 目標 shard 清理臟數據 (如果有必要) 如果目標 shard 上已經存在該 chunk 范圍內的數據,則肯定為某次遷移失敗導致的臟數據,先將這些數據清理掉。 目標 shard 向源 shard 發送 _migrateClone 命令讀取 chunk 范圍內的所有文檔并寫入到本地,即遷移 chunk 全量數據,遷移完后更新狀態為 STEADY(可以理解為全量遷移完成的狀態)。 源 shard 會不斷調用查詢目標 shard 上的遷移狀態,看是否為 STEADY 狀態,如果已經是 STEADY 狀態,就會停止源 shard 上的寫操作(通過對集合加互斥寫鎖實現)。接下來發送 _recvChunkCommit 告訴目標 shard 不會再有新的寫入了。 目標 shard 的遷移線程不斷向源 shard 發送 _transferMods 命令,讀取遷移過程中的增量修改,并應用到本地,增量遷移完成后,向源確認 _recvChunkCommit 的結果。 源 shard 收到 _recvChunkCommit 的結果,整個數據遷移的步驟完成。 Step4:源 shard 更新 config server 元數據 數據遷移完成后,源 shard 就會向 config server 更新 chunk 對應的 shard 信息,同時也會更新 chunk 的版本信息,這樣 mongos 發現本地版本更低就會主動的 reload 元數據,具體機制參考 MongoDB Sharded Cluster 路由策略。 Step5:源 shard 刪除 chunk 數據 chunk 遷移到目標 shard 后,源上的 chunk 就沒有必要再保存了,源 shard 會將 chunk 數據刪除,默認情況下源 shard 會將刪除操作加入到隊列,異步刪除,如果 moveChunk 時,指定了 _waitForDelete 參數為 true,則同步刪除完再返回。 一旦源shard 查詢到目標 shard 進入到 STEADY 狀態了,源 shard 就會進入臨界區,測試源上的寫就會排隊等待。等整個遷移完了,這些等待的寫操作就會繼續執行,但此時 chunk 的版本號已經更新了,會告訴客戶端版本過低,客戶端重新從 config server 讀取配置,此時拿到的路由信息里 chunk 已經在目標 shard 了,然后寫會發往目標 shard 。復制集: 數據同步
Secondary初次同步數據時,會先進行init sync,從Primary(或其他數據更新的Secondary)同步全量數據,然后不斷通過tailable cursor從Primary的local.oplog.rs集合里查詢最新的oplog并應用到自身。
oplog: 冪等(incr會轉為set),循環覆蓋,
順序保證:寫入 oplog前,會先加鎖給 oplog 分配時間戳,并注冊到未提交列表里,正式寫入 oplog,在寫完后,將對應的 oplog 從未提交列表里移除,在拉取 oplog 時若未提交列表為空,所有 oplog 都可讀,否則只能到未提交列表最小值以前的 oplog
Secondary 拉取到一批 oplog 后,在重放這批 oplog 時,會加一個特殊的 Lock::ParallelBatchWriterMode 的鎖,這個鎖會阻塞所有的讀請求,直到這批 oplog 重放完成
client與復制集心跳,復制集之間心跳
復制集成員間默認每2s會發送一次心跳信息,如果10s未收到某個節點的心跳,則認為該節點已宕機;如果宕機的節點為Primary,Secondary(前提是可被選為Primary)會發起新的Primary選舉。Bully算法。
每個節點都傾向于投票給優先級最高的節點(oplog時間戳,一樣誰先就誰)
優先級為0的節點不會主動發起Primary選舉
當Primary發現有優先級更高Secondary,并且該Secondary的數據落后在10s內,則Primary會主動降級,讓優先級更高的Secondary有成為Primary的機會。
如果Primary與大多數的節點斷開連接,Primary會主動降級為Secondary
當復制集內存活成員數量不足大多數時,整個復制集將無法選舉出Primary,復制集將無法提供寫服務,處于只讀狀態
當Primary宕機時,如果有數據未同步到Secondary,當Primary重新加入時,如果新的Primary上已經發生了寫操作,則舊Primary需要回滾部分操作,以保證數據集與新的Primary一致。舊Primary將回滾的數據寫到多帶帶的rollback目錄下,數據庫管理員可根據需要使用mongorestore進行恢復。
Bully
如果P是最大的ID,直接向所有人發送Victory消息,成功新的Leader;否則向所有比他大的ID的進程發送Election消息 如果P再發送Election消息后沒有收到Alive消息,則P向所有人發送Victory消息,成功新的Leader 如果P收到了從比自己ID還要大的進程發來的Alive消息,P停止發送任何消息,等待Victory消息(如果過了一段時間沒有等到Victory消息,重新開始選舉流程) 如果P收到了比自己ID小的進程發來的Election消息,回復一個Alive消息,然后重新開始選舉流程 如果P收到Victory消息,把發送者當做Leader部署
Primary
Secondary:
Arbiter節點只參與投票,不能被選為Primary,并且不從Primary同步數據,偶數時加入
Priority0節點的選舉優先級為0,不會被選舉為Primary
Vote0復制集成員最多50個,參與Primary選舉投票的成員最多7個,其他成員(Vote0)
Hidden(Vote0)可使用Hidden節點做一些數據備份、離線計算的任務,不會影響復制集的服務。
Delayed節點必須是Hidden節點,并且其數據落后與Primary一段時間(錯誤恢復)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/19520.html
摘要:安裝全過程環境基本情況我是在電腦下安裝的系統位,這個也是導致我安裝的時候出現異常提示,原因可能是的版本是位的,我應該再找一個位的,但事實上我找不到。 簡述 之前講了一些關于MongoDB的知識,出人意料的受歡迎,也讓我很吃驚,所以今天打算分享一些我在自己計算機的虛擬機的centos系統下安裝MongoDB的經歷,希望感興趣的你們在安裝MongoDB的時候出現問題可以來看看我是怎么安裝的...
摘要:安裝全過程環境基本情況我是在電腦下安裝的系統位,這個也是導致我安裝的時候出現異常提示,原因可能是的版本是位的,我應該再找一個位的,但事實上我找不到。 簡述 之前講了一些關于MongoDB的知識,出人意料的受歡迎,也讓我很吃驚,所以今天打算分享一些我在自己計算機的虛擬機的centos系統下安裝MongoDB的經歷,希望感興趣的你們在安裝MongoDB的時候出現問題可以來看看我是怎么安裝的...
摘要:安裝全過程環境基本情況我是在電腦下安裝的系統位,這個也是導致我安裝的時候出現異常提示,原因可能是的版本是位的,我應該再找一個位的,但事實上我找不到。 簡述 之前講了一些關于MongoDB的知識,出人意料的受歡迎,也讓我很吃驚,所以今天打算分享一些我在自己計算機的虛擬機的centos系統下安裝MongoDB的經歷,希望感興趣的你們在安裝MongoDB的時候出現問題可以來看看我是怎么安裝的...
閱讀 2538·2021-10-12 10:12
閱讀 1720·2019-08-30 15:52
閱讀 2454·2019-08-30 13:04
閱讀 1741·2019-08-29 18:33
閱讀 967·2019-08-29 16:28
閱讀 454·2019-08-29 12:33
閱讀 2062·2019-08-26 13:33
閱讀 2366·2019-08-26 11:36