這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
項目地址:https://code.google.com/p/weed-fs/
weed-fs是一個簡單且高效能的分布式儲存系統, 它有兩個目標:
1、儲存海量檔案 2、快速存取所存的檔案
weed-fs選擇了 key~file 映射的方式實現檔案定址, 而不是POSIX檔案系統已有的機制, 這有點類似於nosql系統, 你可以稱之為“NoFS”
weed-fs的實現機制是管理volumes伺服器, 而不是在一個中心階段管理所有的元檔案, volumes伺服器可以管理檔案及其元檔案, 這種機制可以大大的緩解了中心節點的壓力, 並且可以將元檔案儲存在volumes伺服器的記憶體中, 而且檔案自動採用Gzip 壓縮 , 從而保證了檔案的訪問速度
weed-fs的理論模型可參考 Weed-FS models after Facebook's Haystack design paper. http://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf
使用方式
weed-fs的master節點預設運行在9333連接埠,而volume節點運行在 8080 連接埠, 比如可以通過以下方式啟動一個master節點和兩個volume節點, 這裡所有節點跑在localhost上, 但你可以跑在多台機器上
啟動master節點 ./weed master
啟動volume節點
weed volume -dir="/tmp" -volumes=0-4 -mserver="localhost:9333" -port=8080 -publicUrl="localhost:8080" & weed volume -dir="/tmp/data2" -volumes=5-7 -mserver="localhost:9333" -port=8081 -publicUrl="localhost:8081" &
寫檔案
一個簡單的儲存檔案的例子 curl http://localhost:9333/dir/assign {"fid":"3,01637037d6","url":"127.0.0.1:8080","publicUrl":"localhost:8080"}
第一步發送http GET請求獲得檔案的fid和volume伺服器的url: curl -F file=@/home/chris/myphoto.jpg http://127.0.0.1:8080/3,01637037d6 {"size": 43234}
第二步發送http的 multipart POST請求(url+'/'+fid) 儲存實際的檔案
儲存檔案ID
你可以儲存檔案fid, 3,01637037d6到任何一個資料庫中, 3表示volume伺服器id,這是一個無符號的32位整型數字, 逗號後面的 01表示檔案id,這是一個無符號的64位整型 ,最後的637037d6表示檔案cookie, 它是一個無符號的32位整型, 使用者保護url的安全訪問 檔案ID和cookie ID都是十六進位編碼, 你可以按照你自己的格式對元組進行儲存, 比如把fid當作字串,理論上你需要 8+1+16+8=33 bytes個位元組
讀取檔案
這裡有一個如何根據url訪問的例子
curl http://localhost:9333/dir/lookup?volumeId=3{"Url":"127.0.0.1:8080","PublicUrl":"localhost:8080"}
首先通過volumeId查詢 volume 伺服器的url, 由於通常情況下, volume 伺服器不會很多, 也不會經常變動,所以你可以緩衝查詢結果 現在你可以通過url從volume伺服器上載入所需要的檔案: http://localhost:8080/3,01637037d6.jpg
架構
對於大部分的分布式儲存系統, 會把檔案分成很多chunk, 中心節點儲存檔案名稱與chunk索引的映射,chunk索引中包含chunk server 和chunk handler等資訊, 這種方式不能處理有效處理大量的小檔案,而且訪問請求也會通過master節點, 在高並發的情況下, 響應會很慢。
在weed-fs中, 採用volumes server管理資料, 每個volume的大小為32GB,並且能夠持有大量的檔案,每個儲存節點有多個volume節點,master節點只需要管理volume的中繼資料即可,而實際檔案的元檔案則儲存在各個 volume 中, 每個元檔案的大小為16 bytes,所有的檔案訪問均可在記憶體中處理,而硬碟操作僅僅是在實際的檔案讀取時才開始
Master Server and Volume Server
架構非常簡單,實際資料存放區在volumes裡, 一個volume伺服器包含多個volumes, 可同時支援讀寫操作,所有的volumes被 master server管理, master server包含了volume與volume server的映射關係,這種靜態對應關係可以很輕鬆的被緩衝
對於每次的寫請求, master server也會組建檔案的key, 因為寫沒有讀那麼頻繁, 所以一個master server可就可以應對大量的請求
讀寫檔案
但用戶端發出寫請求, master server 返回 , 之後用戶端想 volume 節點發出POST請求, 以REST的方式傳送檔案內容,當用戶端需要讀取檔案, 它需要向master server或者緩衝中擷取, 最後用過public url擷取內容
儲存大小
在當前的設計中, 每個volume可以儲存32GB的資料, 所以單個檔案的大小是受制於volume的大小的, 但這個容量是可以在代碼中調整的
記憶體儲存
所有 volume server上的元檔案資訊是儲存在記憶體中的, 而不需要從硬碟中讀取, 每個元檔案都是16位元組大小的映射表
同類產品比較
HDFS的特點是分割大檔案, 能很完美的讀寫大檔案 WeedFS的特點是偏向於小檔案, 追求更高的速度和並發能力
MogileFS有三層組件: tracers, database, storage nodes. WeedFS有兩層組件:directory server, storage nodes. 多一層組件就意味著:很慢的訪問、很複雜的操作以及更高的出錯幾率
GlusterFS是跟POSIX規範完全相容的, 所以更複雜 WeedFS只有一部分相容POSIX
Mongo's GridFS 採用MongoDB管理分隔後的chunks, 每次的讀寫請求都需要資料的查詢元檔案資訊,對於少量請求是沒有問題的, 但對於高並發的情境, 它很容易掛掉 WeedFS採用volume管理實際的資料, 查詢任務分攤到各個volume節點, 所以很容易應對高負載的情境