1. 程式人生 > >Ceph單機引擎FileStore簡介

Ceph單機引擎FileStore簡介

Ceph作為一個高可用和強一致性的軟體定義儲存實現,去使用它非常重要的就是了解其內部的IO路徑和儲存實現。這篇文章主要介紹在IO路徑中最底層的ObjectStore的實現之一FileStore。


ObjectStore

ObjectStore是Ceph OSD中最重要的概念之一,它封裝了所有對底層儲存的IO操作。從上圖中可以看到所有IO請求在Clieng端發出,在Message層統一解析後會被OSD層分發到各個PG,每個PG都擁有一個佇列,一個執行緒池會對每個佇列進行處理。

當一個在PG佇列裡的IO被提出後,該IO請求會被根據型別和相關附帶引數進行處理。如果是讀請求會通過ObjectStore提供的API獲得相應的內容,如果是寫請求也會利用ObjectStore提供的事務API將所有寫操作組合成一個原子事務提交給ObjectStore。ObjectStore通過介面對上層提供不同的隔離級別,目前PG層只採用了Serializable級別,保證讀寫的順序性。

ObjectStore主要介面分為三部分,第一部分是Object的讀寫操作,類似於POSIX的部分介面,第二部分是Object的屬性(xattr)讀寫操作,這類操作的特徵是kv對並且與某一個Object關聯。第三部分是關聯Object的kv操作(在Ceph中稱為omap),這個其實與第二部分非常類似,但是在實現上可能會有所變化。

目前ObjectStore的主要實現是FileStore,也就是利用檔案系統的POSIX介面實現ObjectStore API。每個Object在FileStore層會被看成是一個檔案,Object的屬性(xattr)會利用檔案的xattr屬性存取,因為有些檔案系統(如Ext4)對xattr的長度有限制,因此超出長度的Metadata會被儲存在DBObjectMap裡。而Object的omap則直接利用DBObjectMap實現。因此,可以看出xattr和omap操作是互通的,在使用者角度來說,前者可以看作是受限的長度,後者更寬泛(API沒有對這些做出硬性要求)。

FileJournal


為了縮小寫事務的處理時間,提高寫事務的處理能力並且實現事務的原子性,FileStore引入了FileJournal,所有寫事務在被FileJournal處理以後都會立即返回(上圖中的第二步)。FileJournal類似於資料庫的writeahead日誌,使用O_DIRECT和O_DSYNC每次同步寫入到journal檔案,完成後該事務會被塞到FileStore的op queue。事務通常有若干個寫操作組成,當在中間過程程序crash時,journal給OSD recover提供了完備的輸入。FileStore會存在多個thread從op queue裡獲取op,然後真正apply到檔案系統上對應的Object(Buffer IO)。當FileStore將事務落到disk上之後,後續的該Object的讀請求才會繼續(上圖中的第五步)。當FileStore完成一個op後,對應的Journal可以丟棄這部分日誌。

實際上並不是所有的檔案系統都按照這個順序,一般來說如Ceph推薦的Ext4和XFS檔案系統會先寫入Journal,然後再寫入Filesystem,而COW(Copy on Write)檔案系統如Btrfs和ZFS會同時寫入Journal和FileSystem。

DBObjectMap


DBObjectMap是FileStore的一部分,利用KeyValue資料庫實現了ObjectStore的第三部分API,DBObjectMap主要複雜在其實現了clone操作的no-copy。因為ObjectStore提供了clone API,提供對一個Object的完全clone(包括Object的屬性和omap)。DBObjectMap對每一個Object有一個Header,每個Object聯絡的omap(kv pairs)對會與該Header聯絡,當clone時,會產生兩個新的Header,原來的Header作為這兩個新Header的parent,這時候無論是原來的Object還是cloned Object在查詢或者寫操作時都會查詢parent的情況,並且實現copy-on-write。那麼Header如何與omap(kv pairs)聯絡呢,首先每個Header有一個唯一的seq,然後所有屬於該Header的omap的key裡面都會包含該seq,因此,利用KeyValueDB的提供的有序prefix檢索來實現對omap的遍歷。

上面提到FileStore會將每個Object作為一個檔案,那麼Object的一些屬性會與Object Name一起作為檔名,Object 所屬的PG會作為檔案目錄,當一個PG內所包含的檔案超過一定程度時(在目錄內檔案太多會造成檔案系統的lookup效能損耗),PG會被分裂成兩個PG。