HDFS租約機制

2021-07-23 19:33:41 字數 3632 閱讀 8677

在hdfs中,當每次客戶端使用者往某個檔案中寫入資料的時候,為了保持資料的一致性,此時其它客戶端程式是不允許向此檔案同時寫入資料的。那麼hdfs是如何做到這一點的呢?答案是租約(lease)。換句話說,租約是hdfs給予客戶端的乙個寫檔案操作的臨時許可證,無此證件者將不被允許操作此檔案。本文我們將要深入分析hdfs內部的租約機制,包括租約的新增、移除、管理操作等等。

hdfs租約可能很多使用hdfs的人都或多或少都知道一些,大致的理解一般如下:「客戶端在每次讀寫hdfs檔案的時候獲取租約對檔案進行讀寫,檔案讀取完畢了,然後再釋放此租約」。但是是否有人仔細研究過這個租約內部到底包含了什麼資訊呢,它與租約持有者也就是客戶端使用者是一種怎樣的邏輯關係呢?首先我們需要了解的就是這個問題。下面是hdfs租約的相關定義:

綜合上述3點,租約的結構關係如圖1-1所示。

圖 1-1 租約內部結構

租約類**中的定義如下:

class lease 

});// 檔案id對租約的對映圖

private

final hashmapleasesbyid = new hashmap<>();

...

圖形展示效果如圖1-2所示。

圖 1-2 hdfs內部儲存的租約對映關係

hdfs儲存多種對映關係是為了方便租約的多維度查詢,至少目前來看,按照租約持有者,正在寫的檔案id都可以直接查到對應的租約物件。

在leasemanager租約管理器中,還有一件重要的事情是定期釋放過期的租約物件。這個操作可以避免檔案租約長期不釋放導致其他客戶端檔案無法寫檔案的問題。

因為在某些異常情況下,客戶端程式可能在寫完檔案後,沒有正常關閉檔案,導致檔案始終處於正在寫的狀態中,此檔案在對應的租約中沒有被真正的移除掉。

leasemanager中的解決辦法是啟動乙個定時的監控執行緒,來釋放過期的租約。週期檢測線程主方法如下:

public

void

run()

} finally

// 進行租約間隔檢測時間的睡眠,預設2秒

thread.sleep(fsnamesystem.getleaserecheckintervalms());

} catch(interruptedexception ie)

} catch(throwable e) }}

從上面的**我們可以看出,這是乙個持續執行的操作,我們進入checklease方法,先來看checklease的頭幾行**的執行邏輯,

synchronized

boolean checkleases()

// 進行檔案的關閉,在此過程中,此檔案id將從此租約中移除

boolean completed = fsnamesystem.internalreleaselease(

leasetocheck, p, iip,

hdfsserverconstants.namenode_lease_holder);

...} catch (ioexception e)

// 如果發現租約檢測時間到了,則終止當前操作

if (ismaxlockholdtoreleaselease(start))

}// 從租約中移除異常檔案id

for(long id : removing)

}return needsync;

}

通過上述**,租約檢測的操作可以歸納為如下步驟:

租約檢測過程如圖1-3所示。

圖 1-3 hdfs租約的週期性檢測過程

leaserenewer物件的作用在於定時更新dfsclient使用者所持有的租約。每個使用者對應乙個leaserenewer更新器物件,而每個leaserenewer物件內部會維護乙個dfsclient客戶端列表。在leaserenewer的主方法中,會定期的執行dfsclient客戶端對應租約的renew操作。當dfsclient端所操作的檔案都被關閉了,此dfsclient將從leaserenewer的客戶端列表中進行移除,這就意味著此dfsclient所對應的租約將不再被更新,最後將會被leasemanager進行過期移除操作。

講述完租約的概念以及管理之後,我們來分析租約的新增到釋放的過程。以我們對於租約的乙個傳統概念應該是這樣乙個過程:首先在進行檔案寫操作時,進行租約的新增,然後操作結束之後,進行租約的釋放。但是猜想歸猜想,事實上究竟是否如此呢?下面我們從hdfs**層面對此進行分析。

首先是hdfs租約的新增,租約的新增的確是在每次hdfs寫檔案操作的時候進行的,以追加寫操作為例:

final inodesinpath iip, final string leaseholder,

final string clientmachine, final

boolean newblock,

final

boolean writetoeditlog, final

boolean logretrycache)

throws ioexception

這裡的beginfilelease操作的意思不是新增新租約的意思,而是說開始對此檔案所屬的租約開啟定時更新操作,執行的更新操作是leaserenewer的run方法

最後我們來看租約的檢查,我們看看hdfs如何利用租約來保證只有乙個客戶端程式可以寫資料到某個檔案的。hdfs租約的檢查方法為fsnamesystem的checklease方法。此方法在getadditionaldatanode和fsync方法中被呼叫,這表明了租約檢查發生以下在兩個時候:

這裡我們以getadditionaldatanode方法為例:

locatedblock getadditionaldatanode(string src, long fileid,

final extendedblock blk, final datanodeinfo existings,

final string storageids,

final setexcludes,

final int numadditionalnodes, final string clientname

) throws ioexception

...// 獲取當前檔案的操作者即租約持有者

final string owner = file.getfileunderconstructionfeature().getclientname();

// 如果當前操作者不是租約持有者,則丟擲異常

if (holder != null && !owner.equals(holder))

return file;

}

所以當我們在hdfs的日誌中看到諸如「client (=***) is not the lease owner…」這種錯誤的時候,就表明當前有多個客戶端程式同時在寫某個檔案。

HDFS租約機制

hdfs中,當乙個客戶端往hdfs某個檔案寫入資料的時候,為了保持資料的一致性,其他客戶端是不允許同時寫入的。為了實現這一機制,hdfs引入了租約的概念。簡而言之,租約是hdfs 給與客戶端可以寫入某個檔案的臨時許可證,沒有此證件或者租約到期都不能繼續向該檔案寫入資料。一 租約的屬性或者要素 1 租...

分布式租約機制

租約 lease 在分布式中一般描述如下 如果頒發者的時鐘比接收者的時鐘慢,則當接收者認為 lease 已經過期的時候,頒發者依舊認為 lease 有效。接收者可以用在 lease 到期前申請新的 lease 的方式解決這個問題。如果頒發者的時鐘比接收者的時鐘快,則當頒發者認為 lease 已經過期...

HDFS儲存的機制之HDFS讀寫流程

7步 1.hdfs提供的客戶端client,向遠端的namenode發起rpc請求。2.namenode會檢查要建立的檔案是否已經存在,建立者是否有許可權進行操作。成功則會檔案建立乙個記錄,否則會讓客戶端丟擲異常。3.a 當客戶端client開始寫入檔案的時候,客戶端會將檔案切分成多個packets...