1. 程式人生 > >深入剖析MongoDB架構(資料儲存架構)

深入剖析MongoDB架構(資料儲存架構)

近日,軟體工程師Ricky Ho的在 他的部落格裡發表了一篇關於MongoDB架構( MongoDB Architecture)的博文,雖然這是一個聽起來感覺很寬泛的話題,但是作者在文章中確實對MongoDB由內至外的架構進行了剖析。本文截取了其文章中的幾張重點架構示意圖進行簡要描述。 

1、MongoDB資料檔案內部結構

深入剖析MongoDB架構
  • MongoDB在資料儲存上按名稱空間來劃分,一個Collection是一個名稱空間,一個索引也是一個名稱空間。
  • 同一個名稱空間的資料被分成很多個Extent,Extent之間使用雙向連結串列連線。
  • 在每一個Extent中,儲存了具體每一行的資料,這些資料也是通過雙向連結來連線的。
  • 每一行資料儲存空間不僅包括資料佔用空間,還可能包含一部分附加空間,這使得在資料Update變大後可以不移動位置。
  • 索引以BTree結構實現。
2、在MongoDB中實現事務

深入剖析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。 


3、MongoDB資料同步

深入剖析MongoDB架構 
MongoDB採用Replica Sets模式的同步流程
本流程可簡要描述如下: 

  • 紅色箭頭表示寫操作可以寫到Primary上,然後非同步同步到多個Secondary上。
  • 藍色箭頭表示讀操作可以從Primary或Secondary任意一箇中讀取。
  • 各個Primary與Secondary之間一直保持心跳同步檢測,用於判斷Replica Sets的狀態。
4、分片機制

深入剖析MongoDB架構
  • MongoDB的分片是指定一個分片key來進行,資料按範圍分成不同的chunk,每個chunk的大小有限制。
  • 有多個分片節點儲存這些chunk,每個節點儲存一部分的chunk。
  • 每一個分片節點都是一個Replica Sets,這樣保證資料的安全性。
  • 當一個chunk超過其限制的最大體積時,會分裂成兩個小的chunk。
  • 當chunk在分片節點中分佈不均衡時,會引發chunk遷移操作。
5、伺服器角色

深入剖析MongoDB架構
前面講了分片的機制,下面是具體在分片時幾種節點的角色: 

  • 客戶端訪問路由節點mongos來進行資料讀寫。
  • config伺服器儲存了兩個對映關係,一個是key值的區間對應哪一個chunk的對映關係,另一個是chunk存在哪一個分片節點的對映關係。
  • 路由節點通過config伺服器獲取資料資訊,通過這些資訊,找到真正存放資料的分片節點進行對應操作。
  • 路由節點還會在寫操作時判斷當前chunk是否超出限定大小。如果超出,就分列成兩個chunk。
  • 對於按分片key進行的查詢和update操作來說,路由節點會查到具體的chunk然後再進行相關的工作。
  • 對於不按分片key進行的查詢和update操作來說,mongos會對所有下屬節點發送請求然後再對返回結果進行合併。
  • 轉自:http://www.open-open.com/lib/view/open1348919251822.html