2019獨角獸企業重金招聘Python工程師標準>>>
簡介
NFS4實現“租賃鎖”。每個鎖擁有一樣的“租賃期”。客戶端的讀寫操作將刷新“租賃期”。租賃期到期后,鎖將被服務器釋放。NFS4通過下述“模型”實現對鎖的管理:
1)?清晰地劃分客戶端和服務器;
2)?可靠的鎖的一致性檢測機制
3)?簡單可靠的鎖狀態恢復機制
幾個概念
Client?--?客戶端是訪問NFS服務器的資源的實體。客戶端是包含直接訪問NFS服務器的一個應用程序。客戶端可以是傳統的操作系統遠程文件系統服務的應用程序。客戶端負責維護一個或多個用戶應用程序的NFS鎖。客戶端崩潰或失敗時,它負責管理重新獲取鎖。請注意,多個客戶端可以共享相同的傳輸;多個客戶端可能存在于同一個網絡節點。
Clientid??---?64位的id標識符。客戶端經過認證后,由服務器分配的整型數,用于后續通訊中標識客戶端。
Server??---?負責協調客戶端訪問文件系統的實體。
Stateid??---?128位變量用于標識特定文件狀態(打開和鎖定)。由服務器分配,根據stateid可找到相應的狀態信息表。
關鍵流程
1)?客戶端認證(申請clientid)?
客戶端啟動?-->?發送nfs_client_id4(verifier和id串)?,SETCLIENTID
-->?服務器分配clientid?-->?客戶端發送clientid?給服務器端,二次確認SETCLIENTID_CONFIRM?-->?認證成功(建立server記錄)
2)?狀態建立(申請stateid)?-->?帶狀態的文件操作?-->?撤銷狀態
客戶端用clientid為特定lock_owner發起鎖申請?-->?服務器鎖定文件,并發回stateid?(建立狀態表)-->?客戶端用stateid進行文件讀寫-->?撤銷狀態,即撤銷stateid
NFS?4?為支持文件鎖需要解決的問題:
1)?如何識別客戶端?不同客戶端?客戶端重啟?
2)?如何識別服務器?服務器是否重啟?
3)?如何維護鎖狀態?正常流程?重啟恢復?
4)?如何保證“至多一次”的鎖狀態更新?
5)?狀態同步?客戶端失敗,服務器成功下的狀態同步?
?
1)?如何識別客戶端?不同客戶端?客戶端重啟?
每個客戶端均必須經過服務器端的認證,并獲取服務器端分配的唯一標識符clientid。在后續操作中,NFS系統采用clientid表示該客戶端。
客戶端發起認證時,需提供兩個信息,verifier和id,verifier用于表示該客戶端是否是重啟客戶端(重啟客戶端將撤銷所有此客戶端的鎖狀態);id是該客戶端用戶標識自己身份的唯一字符串。Id串一般由如下幾部分組成:客戶端地址(ip+port),服務器地址(ip+port),?MAC等機器唯一的信息。socket的通訊五元組可作為同一個server下的唯一標識串,加上MAC等信息是為了防止不同客戶端的ip重用。
在上述id生成規則下,不同客戶端將生成唯一的標識串。客戶端重啟時,id不變,僅改變verifier。為了實現重啟時id不變,每個客戶端配一個監控進程,監控進程生成id和verifier,并啟動客戶端,重啟時改變verifier。
?
2)?如何識別服務器?服務器是否重啟?
服務器的標識放在stateid中,由于服務器的唯一性,可用進程id來標識服務器。服務器重啟后,進程id改變,相應的stateid中server標識也將改變,導致stateid失效。同時服務器重啟將導致所有鎖信息丟失(無信息持久化),也導致stateid失效。
?
3)?如何維護鎖狀態?正常流程?重啟恢復?
正常流程:
針對特定文件,lock_owner可申請相應的鎖(狀態申請),得到服務器分配的stateid表示鎖請求成功。在后續操作中,該owner均使用stateid進行文件操作。
異常處理流程:
a)?客戶端失敗:死鎖,網絡不可達,無法正常工作
NFS?4采用的租賃鎖,有特定的租賃期限。若客戶端失敗,服務器不做任何特殊處理(無法區分客戶端正常與否),等待租賃鎖到期,鎖自然釋放。
b)?客戶端重啟
客戶端重啟,服務器根據客戶端發過來的verifier可知客戶端重啟,服務器主動釋放與該客戶端id相關的所有鎖。
c)?服務器失敗?--?無法處理,只能重啟服務器
d)?服務器重啟
服務器重啟將導致所有的客戶端鎖狀態失效,客戶端進行文件操作時將知道lock狀態丟失。當lock狀態丟失,client應該重建鎖狀態。
Server重啟后,lease?period期間內為客戶端重建鎖狀態時期。在此期間,server可以阻塞所有的讀、寫、lock等請求,除非server能夠確保不發生鎖沖突(比如持久化鎖狀態于磁盤)!
e)?網絡不可達
網絡不可達,基本等同于客戶端失敗,服務器等待租賃鎖失效。但當網絡不可達和服務器重啟同時出現時,可能出現兩種難以處理的情形,需要持久化存儲鎖狀態方能解決,略去。
?
4)?如何保證“至多一次”的鎖狀態更新?
在和文件鎖相關的操作中(加鎖,升級,降級,解鎖),多次操作是不允許的。這就要求相應的操作具有“至多一次(at-most-once)”語義。為實現“至多一次”的鎖狀態更新,NFS引入“序列化機制”,以應對網絡重傳和重排序。具體實現如下:每個鎖狀態更新請求均攜帶序列號。該序列號是一個連續遞增整數,由客戶端維護,不同lock_owners擁有不同的序列號,初始值為0。服務器在狀態表中緩存最后收到的序列號(last?sequence?number?(L))和應答(response)。只有當下次鎖狀態更新請求的序列號為L+1時,該請求才被視為有效請求!
注意:
a)?客戶端必須保證不多于一個的鎖狀態更新請求!(同一鎖狀態更新請求可多次發送,序列號相同)
b)?當服務器收到相同的鎖狀態更新請求(序列號相同)時,緩存的應答將發送給客戶端,而無相應鎖操作被執行。
?
5)?狀態同步?客戶端失敗,服務器成功下的狀態同步?
當鎖狀態更新請求失敗后,如超時,服務器的鎖狀態可能已經改變。為了保證客戶端的鎖狀態的一致性,客戶端應該重發“失敗”的鎖狀態更新請求,同步狀態,即客戶端必須緩存失敗的鎖狀態更新請求,并在下次提交鎖狀態更新請求前,重發該lock_owner緩存的鎖狀態更新請求!
“二次確認機制”也能確保狀態的一致性,但成本高,重發機制,只有在失敗后才會重新發送,成本低(鎖狀態更新請求遠比客戶端認證頻繁!)。
參考文獻:RFC 3530