1. JuiceFS 源碼閱讀-上

        共 2749字,需瀏覽 6分鐘

         ·

        2021-06-25 20:21

        JuiceFS 源碼閱讀-上

        最近研究文件系統(tǒng),把近期比較火的JuiceFS代碼翻出來看了一下,研究為啥其性能要比CephFS要好。

        背景知識

        參考資源:https://mp.weixin.qq.com/s/HvbMxNiVudjNPRgYC8nXyg

        FUSE 是一個用來實現(xiàn)用戶態(tài)文件系統(tǒng)的框架,這套 FUSE 框架包含 3 個組件:

        • 內(nèi)核模塊 fuse.ko :用來接收 vfs 傳遞下來的 IO 請求,并且把這個 IO 封裝之后通過管道發(fā)送到用戶態(tài);

        • 用戶態(tài) lib 庫 libfuse :解析內(nèi)核態(tài)轉(zhuǎn)發(fā)出來的協(xié)議包,拆解成常規(guī)的 IO 請求;

        • mount 工具 fusermount ;

        背景:一個用戶態(tài)文件系統(tǒng),掛載點為 /tmp/fuse ,用戶二進制程序文件為 ./hello ;當執(zhí)行 ls -l /tmp/fuse 命令的時候,流程如下:
        IO 請求先進內(nèi)核,經(jīng) vfs 傳遞給內(nèi)核 FUSE 文件系統(tǒng)模塊;
        內(nèi)核 FUSE 模塊把請求發(fā)給到用戶態(tài),由 ./hello 程序接收并且處理。處理完成之后,響應原路返回;

        7c2b236ec5eafe40c351cb4bddb13ca3.webp


        JuiceFS架構簡介

        JuiceFS 由三個部分組成:

        1. JuiceFS 客戶端:協(xié)調(diào)對象存儲和元數(shù)據(jù)存儲引擎,以及 POSIX、Hadoop、Kubernetes、S3 Gateway 等文件系統(tǒng)接口的實現(xiàn);

        2. 數(shù)據(jù)存儲:存儲數(shù)據(jù)本身,支持本地磁盤、對象存儲;

        3. 元數(shù)據(jù)引擎:存儲數(shù)據(jù)對應的元數(shù)據(jù),支持 Redis、MySQL、SQLite 等多種引擎;

        65f8758b395336c8863f6e3702f7f706.webp

        JuiceFS 依靠 Redis 來存儲文件的元數(shù)據(jù)。Redis 是基于內(nèi)存的高性能的鍵值數(shù)據(jù)存儲,非常適合存儲元數(shù)據(jù)。與此同時,所有數(shù)據(jù)將通過 JuiceFS 客戶端存儲到對象存儲中。

        a9836478ab2da0d16cbc512e5c2bbdfa.webp

        任何存入 JuiceFS 的文件都會被拆分成固定大小的?"Chunk",默認的容量上限是 64 MiB。每個 Chunk 由一個或多個?"Slice"?組成,Slice 的長度不固定,取決于文件寫入的方式。每個 Slice 又會被進一步拆分成固定大小的?"Block",默認為 4 MiB。最后,這些 Block 會被存儲到對象存儲。與此同時,JuiceFS 會將每個文件以及它的 Chunks、Slices、Blocks 等元數(shù)據(jù)信息存儲在元數(shù)據(jù)引擎中。

        a69d23f4c364422bc33a233ac8a9919c.webp

        使用 JuiceFS,文件最終會被拆分成 Chunks、Slices 和 Blocks 存儲在對象存儲。因此,你會發(fā)現(xiàn)在對象存儲平臺的文件瀏覽器中找不到存入 JuiceFS 的源文件,存儲桶中只有一個 chunks 目錄和一堆數(shù)字編號的目錄和文件。不要驚慌,這正是 JuiceFS 高性能運作的秘訣!

        補充一下源碼中,每個blocks的命名規(guī)則定義,也就是最終存儲在對象存儲系統(tǒng)中的對象key名稱。


        func?(c?*rChunk)?key(indx?int)?string?{
        ????if?c.store.conf.Partitions?>?1?{
        ????????return?fmt.Sprintf("chunks/%02X/%v/%v_%v_%v",?c.id%256,?c.id/1000/1000,?c.id,?indx,?c.blockSize(indx))
        ????}
        ????return?fmt.Sprintf("chunks/%v/%v/%v_%v_%v",?c.id/1000/1000,?c.id/1000,?c.id,?indx,?c.blockSize(indx))
        }
        從命名規(guī)則里面也能看出,數(shù)據(jù)是支持按partition進行分區(qū)存儲的,也就是說最終存儲數(shù)據(jù)的bucket可以是多個,這樣有助于提高并發(fā)能力,特別是AWS S3每個bucket是有TPS性能上限的。

        JuiceFS文件系統(tǒng)golang抽象接口組成

        文件系統(tǒng)定義核心數(shù)據(jù)結(jié)構

        type?FileSystem?struct?{
        ????conf???*vfs.Config
        ????reader?vfs.DataReader
        ????writer?vfs.DataWriter
        ????m??????meta.Meta
        ????logBuffer?chan?string
        }

        下圖為個人理解所畫的抽象接口結(jié)構圖

        d4439f5c7f9eb9c0202dc5ce1bf41073.webp
        • 整個JuiceFS文件系統(tǒng)實現(xiàn)主要拆分為VFS抽象實現(xiàn)和相關的config配置管理兩大部分。

        • 任意文件File操作都涉及到數(shù)據(jù)和元數(shù)據(jù)兩部分內(nèi)容,因此代碼中包含數(shù)據(jù)處理相關的DataReader和DataWriter兩個抽象接口,用來處理數(shù)據(jù)的讀取和寫入兩類請求。而元數(shù)據(jù)抽象出Meta一個數(shù)據(jù)庫相關的接口,基于這個接口目前官方實現(xiàn)了dbMeta也就是兼容SQL相關的元數(shù)據(jù)實現(xiàn),以及redisMeta實現(xiàn)(基于redis)。從性能表現(xiàn)來看,redis比MySQL性能要好3~5倍左右。具體可以參考這個

        • 所有的數(shù)據(jù)讀寫操作都要和本地緩存進行交互(Chunk->Slice->block(page)三個層級進行管理),緩存目前主要實現(xiàn)了基于本地文件系統(tǒng)diskStore和基于內(nèi)存緩存cacheStore(堆空間)兩種類型。數(shù)據(jù)寫入和讀取最終都是由對應的緩存模塊同步到遠程的ObjectSotrage。

        • config主要負責對本地緩存、元數(shù)據(jù)引擎連接信息等相關的配置。


        JuiceFS支持的數(shù)據(jù)列表:

        https://github.com/juicedata/juicefs/blob/main/docs/zh_cn/databases_for_metadata.md

        JuiceFS元數(shù)據(jù)redis與MySQL性能對比測試:

        https://github.com/juicedata/juicefs/blob/main/docs/en/metadata_engines_benchmark.md

        下圖是源碼中對ChunkStore的抽象接口定義,通過NewReader和NewWriter生成對應的Reader讀取抽象和Writer抽象,實現(xiàn)數(shù)據(jù)的讀寫相關原子接口。

        94050e1ad8444832adead0375c1a13d9.webp


        08fe3ea35ccd067306ea5776d5c12953.webpd5794fac4a18e3f916eb423148124fd0.webp



        任何廠家的對象存儲產(chǎn)品,只要實現(xiàn)下面的接口抽象,即可實現(xiàn)與JuiceFS的對接。

        74ece1a319a71f229d1bd3919b07a538.webp

        數(shù)據(jù)讀取抽象接口

        下圖是數(shù)據(jù)讀取抽象接口的繼承組合關系

        60759be395563232c2a38e79fea90bec.webp

        最終的數(shù)據(jù)讀取關聯(lián)到rChunk這個struct的相關method方法。

        f93d651bca2c0c80c4ea1dd9633ececb.webp

        數(shù)據(jù)寫入抽象接口

        下圖是數(shù)據(jù)寫入抽象接口的繼承組合關系

        fc8d90ec977cae22dc7653928040d126.webp

        最終的數(shù)據(jù)讀取關聯(lián)到wChunk這個struct的相關method方法。

        3eaa9ac20015027b2b6c438adc8b3c2f.webp


        小節(jié)

        至此,基本理清了JuiceFS的基本構架和核心數(shù)據(jù)結(jié)構,下節(jié)開始對其讀寫具體接口流程進行剖析。


        打個小廣告,團隊持續(xù)招聘存儲開發(fā)和運維同學,感興趣的可以看看之前公眾號網(wǎng)易游戲招聘相關內(nèi)容。



        瀏覽 172
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 亚洲欧美中文日韩在线 | 欧美日韩三级片 | 孕妇H圆房~H嗯啊呻吟动漫 | 国产操屄直播 | 久久成人久久爱 |