AppBoxFuture(五): 分佈式文件存儲-Store Everything

  原本本篇是想介紹前端組件化開發用戶界面,發現框架還未實現文件存儲,本來計劃是後續設計開發的,索性把計劃提早,因此本篇將介紹基於Raft實現分佈式的文件存儲引擎。html

一. 實現思路

  既然是分佈式存儲,就須要解決如下幾個關鍵問題:前端

  • 如何將文件以多副本的形式存儲在集羣的節點上,且保證副本間的一致性?這個問題可基於Raft協議實現相應的狀態機來解決;
  • 如何將大量的文件分組,即如何劃分多個Raft組?這個問題可經過在目錄元數據內保存多個Raft組信息,每一個組存儲限制在64M(暫定)來解決;
  • 如何存儲與管理目錄及文件的元數據?這個問題可經過實現元數據狀態機來管理,利用已實現的KV存儲引擎來存儲元數據;
  • 如何保證元數據與文件數據的一致性?這個問題開始時想用已實現的EntityStore的事務引擎來解決,雖能保證強一致性但邏輯複雜,性能損失大。所以放棄了強一致性改成保證最終一致性,元數據狀態機及文件狀態機內都有定時器來檢查不一致的狀態。

1. 元數據存儲-BlobMetaStateMachine

  開始時想設計爲一個集羣對應一個BlobMetaRaftGroup,後來考慮到單個RaftGroup可能會壓力較大,因此改成每一個Application對應一個BlobMetaRaftGroup。每一個元數據狀態機主要存儲如下各項信息:git

  • 目錄元數據:包括目錄名稱及標識,該目錄下分配了多少個Chunk,每一個Chunk佔用了多少空間,隸屬於哪一個RaftGroup等;
  • 文件元數據:包括文件名稱及標識,該文件隸屬的目錄標識及隸屬的ChunkRaftGroup標識等;
  • Chunk元數據: 包括Chunk的RaftGroup內的各個RaftNode分配在集羣的哪一個節點上;
  • 寫鎖數據:用於併發寫時加鎖。

  確認了須要存儲哪些信息後,就須要確認如何將這些數據映射至底層的KV存儲,既要保證高效又要方便Api檢索這些元數據,通過一些嘗試後最終定爲如下方案。github

目錄元數據 Key

TypeFlag AppId 目錄名稱UTF8編碼
8bit 8bit n bit
  • TypeFlag = 0
  • 注意:最後一個'/' 0x2F被替換爲0x00,以方便掃描某一目錄下全部子目錄

目錄元數據 Value

目錄Id Chunk RaftGroup數量 Chunk RaftGroupIds
128bit 16bit n * 64bit

文件元數據 Key

TypeFlag AppId 目錄Guid 分隔佔位 名稱UTF8編碼
8bit 8bit 128bit 8bit n bit
  • TypeFlag = 1
  • 分隔佔位始終 = 0

文件元數據 Value

文件Id 文件大小 Chunk RaftGroupId
128bit 32bit 64bit

2. 文件存儲-BlobChunkStateMachine

  根據上述設計,每一個目錄下的文件分紅了多個存儲組(BlobChunkRaftGroup),原本想用MemoryMapFile來實現底層Chunk存儲,但考慮到有更重要的功能要實現因此暫偷懶直接利用Linux文件系統來存儲文件,狀態機Apply文件寫命令時,將文件直接寫入節點運行時blob/ChunkRaftGroupId/目錄下。瀏覽器

3. 讀寫流程

  • 讀流程較簡單: 發送讀元數據命令至BlobMetaRaftGroup獲取文件元數據(緩存),而後再分小塊發讀命令至目標ChunkRaftGroup獲取文件小塊數據;
  • 寫流程要考慮元數據與文件數據的一致性,還要考慮在目錄下無可用ChunkRaftGroup時建立新的組,具體參考如下設計草圖:

二. 實現效果

  根據以上設計在經歷了1個月的編碼後已初步實現(其中約一半時間在更改架構,拋棄了Mono依賴,改成Hosting CoreCLR,性能提高1倍),在框架IDE內每一個Application內有個"BlobStore"節點,以下圖所示可測試上傳文件,而後經過瀏覽器訪問上傳至/pub目錄內的文件(http://{地址:端口}/blob/{app名稱}/{文件路徑} eg: http://xx.xx.xx.xx:5000/blob/sys/imgs/aa.jpg
緩存

  做者簡單測試了一下經過框架WebHost下載文件的性能(測試時還沒有實現緩存元數據, 虛擬機I74C8G),以下圖所示:
架構

三. 本篇小結

  本實現適用於存儲大量小文件,如業務單證的附件,或者用於OA系統做爲文檔庫。目前只是實現了基本的上傳下載功能,刪除、重命名、Chunk合併等功能還沒有實現,另待未來框架實現反向索引後再實現全文搜索功能。併發

  框架已更新,如何安裝測試請參考AppBoxFuture(一): Hello Future!。若是您有問題或Bug報告,請留言或在Github提交Issue。app

相關文章
相關標籤/搜索