如果有中心節(jié)點,則數(shù)據(jù)節(jié)點定期和中心節(jié)點進行通信,匯報自己的數(shù)據(jù)塊的相關(guān)信息,中心節(jié)點將其與自己維護的信息進行對比。如果某個數(shù)據(jù)塊的 checksum 不對,則表明該數(shù)據(jù)塊被損壞了;如果某個數(shù)據(jù)塊的 version 不對,則表明該數(shù)據(jù)塊過期了。
在有中心節(jié)點的情況下,這個工作比較好做,中心節(jié)點就包辦了——判斷哪臺存儲節(jié)點壓力較大,判斷把哪些文件遷移到何處,更新自己的 meta 信息,遷移過程中的寫入怎么辦,發(fā)生重命名怎么辦。無需上層應(yīng)用來處理。
如果沒有中心節(jié)點,那代價比較大,在系統(tǒng)的整體設(shè)計上,也是要考慮到這種情況,比如ceph,它要采取邏輯位置和物理位置兩層結(jié)構(gòu),對Client暴露的是邏輯層 (pool 和 place group),這個在遷移過程中是不變的,而下層物理層數(shù)據(jù)塊的移動,只是邏輯層所引用的物理塊的地址發(fā)生了變化,在Client看來,邏輯塊的位置并不會發(fā)生改變。2、中心節(jié)點的伸縮
如果有中心節(jié)點,還要考慮它的伸縮性。由于中心節(jié)點作為控制中心,是主從模式,那么在伸縮性上就受到比較大的限制,是有上限的,不能超過單臺物理機的規(guī)模。我們可以考慮各種手段,盡量地抬高這個上限。有幾種方式可以考慮:以大數(shù)據(jù)塊的形式來存儲文件——比如 HDFS 的數(shù)據(jù)塊的大小是 64M,ceph 的的數(shù)據(jù)塊的大小是 4M,都遠遠超過單機文件系統(tǒng)的 4k。它的意義在于大幅減少 meta data 的數(shù)量,使中心節(jié)點的單機內(nèi)存就能夠支持足夠多的磁盤空間 meta 信息。中心節(jié)點采取多級的方式——頂級中心節(jié)點只存儲目錄的 meta data,其指定某目錄的文件去哪臺次級總控節(jié)點去找,然后再通過該次級總控節(jié)點找到文件真正的存儲節(jié)點;中心節(jié)點共享存儲設(shè)備——部署多臺中心節(jié)點,但它們共享同一個存儲外設(shè) / 數(shù)據(jù)庫,meta 信息都放在這里,中心節(jié)點自身是無狀態(tài)的。這種模式下,中心節(jié)點的請求處理能力大為增強,但性能會受一定影響。iRODS 就是采用這種方式。1、中心節(jié)點的高可用
中心節(jié)點的高可用,不僅要保證自身應(yīng)用的高可用,還得保證 meta data 的數(shù)據(jù)高可用。
meta data 的高可用主要是數(shù)據(jù)持久化,并且需要備份機制保證不丟。一般方法是增加一個從節(jié)點,主節(jié)點的數(shù)據(jù)實時同步到從節(jié)點上。也有采用共享磁盤,通過 raid1 的硬件資源來保障高可用。顯然增加從節(jié)點的主備方式更易于部署。
meta data 的數(shù)據(jù)持久化策略有以下幾種方式:直接保存到存儲引擎上,一般是數(shù)據(jù)庫。直接以文件形式保存到磁盤上,也不是不可以,但因為 meta 信息是結(jié)構(gòu)化數(shù)據(jù),這樣相當于自己研發(fā)出一套小型數(shù)據(jù)庫來,復(fù)雜化了。保存日志數(shù)據(jù)到磁盤文件 (類似 MySQL 的 binlog 或 Redis 的 aof),系統(tǒng)啟動時在內(nèi)存中重建成結(jié)果數(shù)據(jù),提供服務(wù)。修改時先修改磁盤日志文件,然后更新內(nèi)存數(shù)據(jù)。這種方式簡單易用。
這些年隨著基礎(chǔ)設(shè)施的發(fā)展,局域網(wǎng)內(nèi)千兆甚至萬兆的帶寬已經(jīng)比較普遍,以萬兆計算,每秒傳輸大約 1250M 字節(jié)的數(shù)據(jù),而 SATA 磁盤的讀寫速度這些年基本達到瓶頸,在 300-500M/s 附近,也就是純讀寫的話,網(wǎng)絡(luò)已經(jīng)超過了磁盤的能力,不再是瓶頸了,像 NAS 網(wǎng)絡(luò)磁盤這些年也開始普及起來。
但這并不代表,沒有必要對讀寫進行優(yōu)化,畢竟網(wǎng)絡(luò)讀寫的速度還是遠慢于內(nèi)存的讀寫。常見的優(yōu)化方法主要有:內(nèi)存中緩存文件內(nèi)容;預(yù)加載數(shù)據(jù)塊,以避免客戶端等待;合并讀寫請求,也就是將單次請求做些積累,以批量方式發(fā)送給 Server 端。
有連續(xù)空間和鏈表空間兩種。連續(xù)空間的優(yōu)勢是讀寫快,按順序即可,劣勢是造成磁盤碎片,更麻煩的是,隨著連續(xù)的大塊磁盤空間被分配滿而必須尋找空洞時,連續(xù)分配需要提前知道待寫入文件的大小,以便找到合適大小的空間,而待寫入文件的大小,往往又是無法提前知道的 (比如可編輯的 word 文檔,它的內(nèi)容可以隨時增大);
為了解決這個問題,出現(xiàn)了索引表——把文件和數(shù)據(jù)塊的對應(yīng)關(guān)系也保存一份,存在索引節(jié)點中 (一般稱為 i 節(jié)點),操作系統(tǒng)會將 i 節(jié)點加載到內(nèi)存,從而程序隨機尋找數(shù)據(jù)塊時,在內(nèi)存中就可以完成了。通過這種方式來解決磁盤鏈表的劣勢,如果索引節(jié)點的內(nèi)容太大,導(dǎo)致內(nèi)存無法加載,還有可能形成多級索引結(jié)構(gòu)。2、文件刪除
怎么回收被刪除或無用的數(shù)據(jù)? 可以從文件的 meta 信息出發(fā)——如果 meta 信息的“文件 - 數(shù)據(jù)塊”映射表中包含了某個數(shù)據(jù)塊,則它就是有用的;如果不包含,則表明該數(shù)據(jù)塊已經(jīng)是無效的了。所以,刪除文件,其實是刪除 meta 中的“文件 - 數(shù)據(jù)塊”映射信息 (如果要保留一段時間,則是把這映射信息移到另外一個地方去)。3、面向小文件的分布式文件系統(tǒng)
針對這種業(yè)務(wù)場景,主流的實現(xiàn)方式是仍然是以大數(shù)據(jù)塊的形式存儲,小文件以邏輯存儲的方式存在,即文件 meta 信息記錄其是在哪個大數(shù)據(jù)塊上,以及在該數(shù)據(jù)塊上的 offset 和 length 是多少,形成一個邏輯上的獨立文件。這樣既復(fù)用了大數(shù)據(jù)塊系統(tǒng)的優(yōu)勢和技術(shù)積累,又減少了 meta 信息。4、文件指紋和去重