您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何進行NFS文件鎖一致性設計原理解析,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
文件鎖是文件系統(tǒng)的最基本特性之一,應用程序借助文件鎖可以控制其他應用對文件的并發(fā)訪問。NFS作為類UNIX系統(tǒng)的標準網(wǎng)絡文件系統(tǒng),在發(fā)展過程中逐步的原生地支持了文件鎖(從NFSv4開始)。NFS從上個世界80年代誕生至今,共發(fā)布了3個版本:NFSv2、NFSv3、NFSv4。NFSv4最大的變化是有“狀態(tài)”了。某些操作需要服務端維持相關(guān)狀態(tài),如文件鎖,例如客戶端申請了文件鎖,服務端就需要維護該文件鎖的狀態(tài),否則其他客戶端沖突的訪問就無法檢測。如果是NFSv3就需要NLM協(xié)助才能實現(xiàn)文件鎖功能,但是有的時候兩者配合不夠協(xié)調(diào)就會容易出錯。而NFSv4設計成了一種有狀態(tài)的協(xié)議,自身就可以實現(xiàn)了文件鎖功能,也就不需要NLM協(xié)議了。
應用程序可以通過fcntl()或flock()系統(tǒng)調(diào)用管理NFS文件鎖,下面NAS使用NFSv4掛載時獲取文件鎖的調(diào)用過程:
從上圖調(diào)用棧容易看出來,NFS文件鎖實現(xiàn)邏輯基本復用了VFS層設計和數(shù)據(jù)結(jié)構(gòu),在通過RPC從Server成功獲取文件鎖后調(diào)用locks_lock_inode_wait()函數(shù)將獲得文件鎖交給到VFS層管理,關(guān)于VFS層文件鎖設計的相關(guān)資料比較多,在此就不再描述了。
文件鎖是典型的非冪等操作,文件鎖操作的重試和Failover會導致文件鎖狀態(tài)視圖在客戶端和服務端間的不一致。NFSv4借助SeqId機制設計了最多執(zhí)行一次的機制,具體方法如下:
針對每個open/lock狀態(tài)Client和Server同時獨立維護seqid,Client在發(fā)起會引起狀態(tài)變化的操作時(open/close/lock/unlock/release_lockowner)會將seqid加1,并作為參數(shù)發(fā)送給Server,假定Client發(fā)送的seqid為R,Server維護的seqid為L,則:
1) 若R == L +1,表示合法請求,正常處理之;
2) 若R == L,表示重試請求,Server將緩存的reply返回即可;
3) 其他情況均為非法請求,決絕訪問。
根據(jù)上述規(guī)則,Server可判斷操作是否為正常、重試或非法請求。
該方法能夠保證每個文件鎖操作在服務端最多執(zhí)行一次,解決了RPC重試帶來的重復執(zhí)行的問題,但是僅靠這一點是不夠的。比如LOCK操作發(fā)送后調(diào)用線程被信號中斷,此后服務端又成功接受并執(zhí)行了該LOCK操作,這樣服務端就記錄了客戶端持有了鎖,但客戶端中卻因為中斷而沒有維護這把鎖,客戶端和服務端間的鎖狀態(tài)視圖不一致就發(fā)生了。因此,客戶端還需配合處理異常場景,最終才能夠做到文件鎖視圖一致性。
由上一節(jié)分析可知,客戶端需要配合處理異常場景才能夠保證文件視圖一致性,那么客戶端設計者主要做了哪些配合的設計呢?目前客戶端主要從SunRPC和NFS協(xié)議實現(xiàn)兩個維度相互配合解決該問題,下面會分別介紹這兩個維度的設計如何保證了文件鎖狀態(tài)視圖一致性。
SunRPC是Sun公司專門為遠程過程調(diào)用設計的網(wǎng)絡通訊協(xié)議,這里從保障文件鎖視圖一致性的維度來了解一下SunRPC實現(xiàn)層面的設計理念:
1) 客戶端使用int32_t類型的xid標識上層使用者發(fā)起的每個遠程過程調(diào)用過程,每個遠程過程調(diào)用的多次RPC重試使用相同的xid標識,這樣就保障了多次RPC重試中任何一個返回就可以告知上層遠程過程調(diào)用已經(jīng)成功,保證了服務端執(zhí)行遠程過程調(diào)用執(zhí)行耗時較長時也能拿到結(jié)果,這一點和傳統(tǒng)的netty/mina/brpc等都需要每個RPC都要有獨立的xid/packetid不同;
2) 服務端設計了DRC(duplicate request cache)緩存最近執(zhí)行的RPC結(jié)果,接收到RPC時會首先通過xid檢索DRC緩存,若命中則表明RPC為重試操作,直接返回緩存的結(jié)果即可,這在一定程度上規(guī)避了RPC重試帶來的重復執(zhí)行的問題。為了避免xid復用導致DRC緩存返回非預期的結(jié)果,開發(fā)者通過下述設計進一步有效地減少復用引起錯誤的概率:
a) 客戶端建立新鏈接時初始xid采用隨機值:
b) 服務端DRC會額外記錄請求的校驗信息,緩存命中時會同時校驗這些信息;
3) 客戶端允許在獲得服務端相應前無限重試,保證調(diào)用者能夠獲得服務端確定性的執(zhí)行結(jié)果,當然這樣的策略會導致無響應時調(diào)用者會一直hang;
4) NFS允許用戶在掛載時通過soft/hard參數(shù)指定SunRPC的重試策略,其中soft模式禁止超時后重試,hard模式則持續(xù)重試。當用戶使用soft模式掛載時NFS實現(xiàn)不保證客戶端和服務端狀態(tài)視圖的一致性,在遇到遠程過程調(diào)用返回超時要求應用程序配合狀態(tài)的清理和恢復,比如關(guān)閉訪問出錯的文件等,然而實踐中很少有應用程序會配合,所以一般情況下NAS用戶都使用hard模式掛載;
總之,SunRPC要解決的核心問題之一是遠程過程調(diào)用執(zhí)行時間是不可控的,協(xié)議設計者為此定制化設計,盡量避免非冪等操作RPC重試帶來的副作用。
應用程序等待遠程過程調(diào)用結(jié)果時允許被信號中斷。當發(fā)生信號中斷時由于沒有得到遠程過程調(diào)用的執(zhí)行結(jié)果,所以客戶端和服務端的狀態(tài)很可能就不一致了,比如加鎖操作在服務端已經(jīng)成功執(zhí)行,但客戶端并不知道這個情況。這就要求客戶端做額外的工作將狀態(tài)和服務端恢復一致。下面簡要分析獲取文件鎖被信號中斷后的處理說明NFS協(xié)議實現(xiàn)層面的一致性設計。
通過獲取NFSv4文件鎖的過程可知,NFSv4獲取文件鎖最終會調(diào)用_nfs4_do_setlk()函數(shù)發(fā)起RPC操作,最終調(diào)用nfs4_wait_for_completion_rpc_task()等待,下面是相關(guān)代碼:
5684 static int _nfs4_do_setlk(struct nfs4_state state, int cmd, struct file_lock fl, int recovery_type)
5685 {
......
5718 task = rpc_run_task(&task_setup_data);
5719 if (IS_ERR(task))
5720 return PTR_ERR(task);
5721 ret = nfs4_wait_for_completion_rpc_task(task);
5722 if (ret == 0) {
5723 ret = data->rpc_status;
5724 if (ret)
5725 nfs4_handle_setlk_error(data->server, data->lsp,
5726 data->arg.new_lock_owner, ret);
5727 } else
5728 data->cancelled = 1;
...... }
Copy
通過分析nfs4_wait_for_completion_rpc_task()實現(xiàn)可知,當ret < 0時,表明獲取鎖過程被信號中,并使用struct nfs4_lockdata的cancelled成員記錄。繼續(xù)查看rpc_task完成后釋放時的回調(diào)函數(shù)nfs4_lock_release():
從上面紅色框中代碼可知,nfs4_lock_release()檢測到存在信號中斷時會調(diào)用nfs4_do_unlck()函數(shù)嘗試將可能成功獲得文件鎖釋放掉,注意此時沒有調(diào)用nfs_free_seqid()函數(shù)將持有的nfs_seqid釋放掉,這是為了:
1) 保證訂正狀態(tài)過程中不會有用戶新發(fā)起的并發(fā)加鎖或者釋放鎖操作,簡化實現(xiàn);
2) 保證hard模式下UNLOCK操作只會在LOCK操作返回后才會發(fā)送,保障已經(jīng)獲得鎖能夠被釋放掉;
客戶端通過上面的方法能夠有效地保證信號中斷后客戶端和服務端鎖狀態(tài)的最終一致性,但也是在損失一部分可用性為代價的。
文件鎖是文件系統(tǒng)原生支持的基礎特性,NAS作為共享的文件系統(tǒng)要面臨客戶端和服務端鎖狀態(tài)視圖一致性的問題,NFSv4.0在一定程度上解決了這個問題,當然,技術(shù)前進的腳步不會停止,NFS的更新迭代也就不會停止,未來的NFS將會有更多的期待。
關(guān)于如何進行NFS文件鎖一致性設計原理解析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。