本文主要介紹NAS支持的NFS協(xié)議版本、NFSv3和NFSv4協(xié)議的功能差異及NFS一致性。
NFS概念
NFS(Network File System),即網(wǎng)絡(luò)文件系統(tǒng)協(xié)議,是一種分布式文件系統(tǒng)協(xié)議,通過NFS協(xié)議,您可以像訪問本地文件一樣訪問遠端系統(tǒng)上的文件。
Linux操作系統(tǒng)和容器建議使用NFS協(xié)議類型的文件系統(tǒng)。如果使用SMB協(xié)議類型的文件系統(tǒng),可能會存在一些兼容性的問題。更多信息,請參見交叉掛載兼容性常見問題。
協(xié)議版本
NFS一共發(fā)布了3個版本:NFSv2、NFSv3、NFSv4。其中,NFSv4包含兩個次版本NFSv4.0和NFSv4.1。
通用型NAS支持NFSv3和NFSv4.0版本。
極速型NAS支持NFSv3版本。
NFSv3和NFSv4.0差異
- 功能
NFSv4.0:是一種有狀態(tài)的協(xié)議,自身實現(xiàn)了文件鎖功能和獲取文件系統(tǒng)根節(jié)點功能。
NFSv3:對文件鎖無感知,同時掛載時可能會覆蓋掉v4寫入的部分。
- 安全性
NFSv4.0增加了安全性,支持RPCSEC-GSS身份認證。
- 請求
NFSv4.0只提供了兩個請求NULL和COMPOUND,所有的操作都整合到COMPOUND中,客戶端可以根據(jù)實際請求將多個操作封裝到一個COMPOUND請求中,增加了靈活性。
- 命令空間
NFSv4.0文件系統(tǒng)的命令空間發(fā)生了變化,服務(wù)器端必須設(shè)置一個根文件系統(tǒng)(fsid=0),其他文件系統(tǒng)掛載在根文件系統(tǒng)上導(dǎo)出。
更多關(guān)于NFS文件系統(tǒng)使用限制,請參見協(xié)議類型限制。
NFS Cache應(yīng)用
在傳統(tǒng)云盤中,所有的數(shù)據(jù)都會被緩存在PageCache中,修改過的Page會被異步刷回服務(wù)端,所以云盤的延時都比較低。但在NFS文件系統(tǒng)中,NFS不會將新創(chuàng)建的文件或者新寫入的內(nèi)容緩存在PageCache中,而是盡快刷回NAS服務(wù)端。因此,當多個ECS共享一個NFS協(xié)議文件系統(tǒng)時,NAS所有的操作都會比云盤多一次網(wǎng)絡(luò)調(diào)用開銷,這個開銷一般在100us ~ 1ms之間。其中,盡快刷回NAS服務(wù)端,則涉及NAS所提供的如下多節(jié)點一致性模型:
基于超時的最終一致性
- T為自適應(yīng)的值。默認值:1s~60s。
- 文件內(nèi)容Cache:指緩存了這個文件的內(nèi)容。
- 目錄子項Cache:緩存了這個目錄下存在哪些文件、不存在哪些文件。
- ECS-1讀取了文件X的0~4K:第一次讀,cache不命中,訪問服務(wù)器,讀取數(shù)據(jù),并緩存在本地。
- ECS-2更新了文件X的0~4K:數(shù)據(jù)寫到服務(wù)端,更新FileAttr中的mtime。
- ECS-1再次讀文件X的0~4K:第二次讀,如果時間距離第一次小于T,由于FileAttr還沒有過期,因此,直接使用緩存中的0~4K。
- ECS-1再次讀文件X的0~4K:第三次讀,如果時間距離第一次大于T,則去訪問服務(wù)端,獲取新的FileAttr,然后發(fā)現(xiàn)mtime變了,因此丟棄cache中的數(shù)據(jù),去服務(wù)端讀。
- ECS-1嘗試查找/a:第一次查找,發(fā)現(xiàn)a不存在,于是在目錄/下緩存一個a不存在的信息。
- ECS-2創(chuàng)建文件/a。
- ECS-1再次查找/a:第二次查找,由于時間小于T,直接使用cache,然后向用戶報錯文件不存在。
- ECS-1 再次訪問/a:第三次查找,由于時間大于T,訪問服務(wù)端,獲取目錄/最新的FileAttr,發(fā)現(xiàn)mtime有變化,則丟棄cache中的數(shù)據(jù),去服務(wù)端查詢/a。
更多有關(guān)NFS超時的最終一致性模型內(nèi)容,請參見NFS。
基于文件close/open的CTO一致性
由于超時的最終一致性無法保證ECS-2可以立刻讀ECS-1寫入的數(shù)據(jù)。因此,為了提升一致性,NFS還提供了基于文件的CTO(close-to-open)一致性保證,即當兩個及以上計算節(jié)點同時讀寫相同的文件時,ECS-1的修改在ECS-2不一定能立即看到。但是,一旦ECS-1打開一個文件,寫入若干數(shù)據(jù),然后執(zhí)行了文件關(guān)閉操作,之后在任何一個計算節(jié)點重新打開該文件都可以保證能訪問到新寫入的數(shù)據(jù)。
例如,生產(chǎn)者ECS生產(chǎn)了文件X,生產(chǎn)完畢后執(zhí)行了close。然后給消息隊列發(fā)一條消息說,文件X生產(chǎn)完畢。消費者ECS訂閱消息隊列,讀到消息X(文件X生產(chǎn)完畢),此時,消費者ECS再去open這個文件,通過open返回的fd去讀取這個文件,則一定能夠讀到文件X的所有內(nèi)容。如果消費者ECS在生產(chǎn)者ECS生產(chǎn)完畢之前,就open了文件X,并且持有了fd,當收到消息后,直接用這個fd去讀,是不保證能夠讀取到最新數(shù)據(jù)的。
關(guān)于解決文件創(chuàng)建或?qū)懭胙舆t的解決方案,請參見如何解決在NFS文件系統(tǒng)中創(chuàng)建文件延遲問題?和如何解決向NFS文件系統(tǒng)中寫入數(shù)據(jù)延遲問題?。