本文圖片來自 Ricky Ho 的博文
MongoDB 構架(
MongoDB Architecture),這是個一聽就感覺很寬泛的話題,但是作者在文章中確實對 MongoDB 由內至外的
架構進行了剖析。本文截取了其文章中的幾張重點架構示意圖片進行簡單描述。希望對大家有用。
MongoDB 數據文件內部結構

- MongoDB 在數據存儲上按命名空間來劃分,一個 collection 是一個命名空間,一個索引也是一個命名空間
- 同一個命名空間的數據被分成很多個 Extent,Extent 之間使用雙向鏈表連接
- 在每一個 Extent 中,保存了具體每一行的數據,這些數據也是通過雙向鏈接連接的
- 每一行數據存儲空間不僅包括數據占用空間,還可能包含一部分附加空間,這使得在數據 update 變大后可以不移動位置
- 索引以 BTree 結構實現
在 MongoDB 中實現事務

眾所周知,MongoDB 只支持對單行記錄的原子性修改,并不支持對多行數據的原子操作。但是通過上圖中的變態操作,實際你也可以自己實現事務。其步驟如圖所未:
- 第 1 步:先記錄一條事務記錄,將要修改的多行記錄的修改值寫到里面,并設置其狀態為 init(如果這時候操作中斷,那么在重新啟動時,會判斷到他處于 init 狀態,從而將其保存的多行修改操作應用到具體的行上)
- 第 2 步:然后更新具體要修改的行,將剛才寫的事務記錄的標識寫到它的 tran 字段中
- 第 3 步:將事務記錄的狀態從 init 變成 pending(如果在這時候操作中斷,那么在重新啟動時,會判斷到它的狀態是 pending 的,這時候查看其所有對應的多條要修改的記錄,如果其 tran 有值,那么就進行第 4 步,如果沒值,說明第 4 步已經執行過了,直接將其狀態從 pending 變成 commited 了就行)
- 第 4 步:將需要修改的多條記錄的相應值修改了,并且 unset 掉之前的 tran 字段
- 第 5 步:將事務記錄那一條的狀態從 pending 變成 commited,事務完成
其實上面的步驟并不罕見,在支持事務的 DBMS 中,其事務原子性提交的保證大多都與上面類似。其實事務記錄的 tran 那條記錄,就類似于這些 DBMS 中的 redolog 一樣。
MongoDB 數據同步

上圖是 MongoDB 采用 Replica Sets 模式的同步流程
- 紅色箭頭表示寫操作寫到 Primary 上,然后異步同步到多個 Secondary 上
- 藍色箭頭表示讀操作可以從 Primary 或 Secondary 任意一個上讀
- 各個 Primary 與 Secondary 之間一直保持心跳同步檢測,用于判斷 Replica Sets 的狀態
分片機制

- MongoDB 的分片是指定一個分片 key 來進行,數據按范圍分成不同的 chunk,每個 chunk 的大小有限制
- 有多個分片節點保存這些 chunk,每個節點保存一部分的 chunk
- 每一個分片節點都是一個 Replica Sets,這樣保證數據的安全性
- 當一個 chunk 超過其限制的最大體積時,會分裂成兩個小的 chunk
- 當 chunk 在分片節點中分布不均衡時,會引發 chunk 遷移操作
服務器角色

上面講了分片的標準,下面是具體在分片時的幾種節點角色 - 客戶端訪問路由節點 mongos 來進行數據讀寫
- config 服務器保存了兩個映射關系,一個是 key 值的區間對應哪一個 chunk 的映射關系,另一個是 chunk 存在哪一個分片節點的映射關系
- 路由節點通過 config 服務器獲取數據信息,通過這些信息,找到真正存放數據的分片節點進行對應操作
- 路由節點還會在寫操作時判斷當前 chunk 是否超出限定大小,如果超出,就分列成兩個 chunk
- 對于按分片 key 進行的查詢和 update 操作來說,路由節點會查到具體的 chunk 然后再進行相關的工作
- 對于不按分片 key 進行的查詢和 update 操作來說,mongos 會對所有下屬節點發送請求然后再對返回結果進行合并
更多詳細內容請看原文:MongoDB Architecture
posted on 2012-12-19 11:52
小果子 閱讀(418)
評論(0) 編輯 收藏 引用 所屬分類:
學習筆記 、
SQL 、
開源