天天看點

NFS4檔案鎖機制探秘

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

1) 如何識别用戶端?不同用戶端?用戶端重新開機?

2) 如何識别伺服器?伺服器是否重新開機?

3) 如何維護鎖狀态?正常流程?重新開機恢複?

4) 如何保證“至多一次”的鎖狀态更新?

5) 狀态同步?用戶端失敗,伺服器成功下的狀态同步?

每個用戶端均必須經過伺服器端的認證,并擷取伺服器端配置設定的唯一辨別符clientid。在後續操作中,NFS系統采用clientid表示該用戶端。

用戶端發起認證時,需提供兩個資訊,verifier和id,verifier用于表示該用戶端是否是重新開機用戶端(重新開機用戶端将撤銷所有此用戶端的鎖狀态);id是該用戶端使用者辨別自己身份的唯一字元串。Id串一般由如下幾部分組成:用戶端位址(ip+port),伺服器位址(ip+port), MAC等機器唯一的資訊。socket的通訊五元組可作為同一個server下的唯一辨別串,加上MAC等資訊是為了防止不同用戶端的ip重用。

在上述id生成規則下,不同用戶端将生成唯一的辨別串。用戶端重新開機時,id不變,僅改變verifier。為了實作重新開機時id不變,每個用戶端配一個監控程序,監控程序生成id和verifier,并啟動用戶端,重新開機時改變verifier。

伺服器的辨別放在stateid中,由于伺服器的唯一性,可用程序id來辨別伺服器。伺服器重新開機後,程序id改變,相應的stateid中server辨別也将改變,導緻stateid失效。同時伺服器重新開機将導緻所有鎖資訊丢失(無資訊持久化),也導緻stateid失效。

正常流程:

針對特定檔案,lock_owner可申請相應的鎖(狀态申請),得到伺服器配置設定的stateid表示鎖請求成功。在後續操作中,該owner均使用stateid進行檔案操作。

異常處理流程:

a) 用戶端失敗:死鎖,網絡不可達,無法正常工作

NFS 4采用的租賃鎖,有特定的租賃期限。若用戶端失敗,伺服器不做任何特殊處理(無法區分用戶端正常與否),等待租賃鎖到期,鎖自然釋放。

b) 用戶端重新開機

用戶端重新開機,伺服器根據用戶端發過來的verifier可知用戶端重新開機,伺服器主動釋放與該用戶端id相關的所有鎖。

c) 伺服器失敗 -- 無法處理,隻能重新開機伺服器

d) 伺服器重新開機

伺服器重新開機将導緻所有的用戶端鎖狀态失效,用戶端進行檔案操作時将知道lock狀态丢失。當lock狀态丢失,client應該重建鎖狀态。

Server重新開機後,lease period期間内為用戶端重建鎖狀态時期。在此期間,server可以阻塞所有的讀、寫、lock等請求,除非server能夠確定不發生鎖沖突(比如持久化鎖狀态于磁盤)!

e) 網絡不可達

網絡不可達,基本等同于用戶端失敗,伺服器等待租賃鎖失效。但當網絡不可達和伺服器重新開機同時出現時,可能出現兩種難以處理的情形,需要持久化存儲鎖狀态方能解決,略去。

在和檔案鎖相關的操作中(加鎖,更新,降級,解鎖),多次操作是不允許的。這就要求相應的操作具有“至多一次(at-most-once)”語義。為實作“至多一次”的鎖狀态更新,NFS引入“序列化機制”,以應對網絡重傳和重排序。具體實作如下:每個鎖狀态更新請求均攜帶序列号。該序列号是一個連續遞增整數,由用戶端維護,不同lock_owners擁有不同的序列号,初始值為0。伺服器在狀态表中緩存最後收到的序列号(last sequence number (L))和應答(response)。隻有當下次鎖狀态更新請求的序列号為L+1時,該請求才被視為有效請求!

注意:

a) 用戶端必須保證不多于一個的鎖狀态更新請求!(同一鎖狀态更新請求可多次發送,序列号相同)

b) 當伺服器收到相同的鎖狀态更新請求(序列号相同)時,緩存的應答将發送給用戶端,而無相應鎖操作被執行。

當鎖狀态更新請求失敗後,如逾時,伺服器的鎖狀态可能已經改變。為了保證用戶端的鎖狀态的一緻性,用戶端應該重發“失敗”的鎖狀态更新請求,同步狀态,即用戶端必須緩存失敗的鎖狀态更新請求,并在下次送出鎖狀态更新請求前,重發該lock_owner緩存的鎖狀态更新請求!

“二次确認機制”也能確定狀态的一緻性,但成本高,重發機制,隻有在失敗後才會重新發送,成本低(鎖狀态更新請求遠比用戶端認證頻繁!)。

本文轉自 zhenjing 部落格園部落格,原文連結:  http://www.cnblogs.com/zhenjing/archive/2011/05/15/NFS4_lock.html ,如需轉載請自行聯系原作者