租約-分佈式緩存一致性的高效容錯機制

租約

租約被提議爲一種基於時間的機制,可提供對分佈式系統中緩存數據的有效一致訪問。非拜占庭式故障會影響性能,而不是正確性,並通過短期租約將其影響降到最低。 緩存引入了確保緩存數據與其主要存儲位置之間一致性的問題。一致的意思是,除了高速緩存的性能優勢外,行爲等同於僅存在單個(未緩存)數據副本。對於大型緩存,維持一致性所需的流量可能是緩存性能的主要因素。分佈式系統可能會遇到部分故障:主機可能崩潰或消息可能丟失。 現有的緩存一致性方法分爲兩策略:假定可靠廣播的方式,因此不能容忍通信故障,或者需要對每次讀取進行一致性檢查的策略,但是卻無法提供良好的性能。建議使用租約作爲一種一致性協議,該協議使用物理時鐘來處理主機和通信故障。

租約基本原理

租約論文節選

租約就是指在一個限定的時間裏面,給與其持有人一定特殊的處理權限。在緩存的情況下,租約授予其持有人控制在租約期間對所覆蓋的數據進行寫入的權限,從而使服務器必須先獲得租戶的批准,然後才能編寫該數據。租約持有人授予寫許可權時,會使本地副本的本地副本無效。

使用租約的緩存需要對數據進行有效的租約(除保留數據外),然後才響應讀取而返回數據,或響應寫而修改數據。從服務器(數據的主存儲站點)獲取數據時,服務器還會返回租約,以保證在租期內不會有任何客戶端寫入數據,除非服務器首先獲得該租約持有人的批准。如果在租約期限內再次讀取了數據(並且該數據仍在高速緩存中),則高速緩存將提供對數據的即時訪問,而無需與服務器通信。租約到期後,讀取數據需要高速緩存首先在數據上擴展租約,如果自從租約過期以來已經修改了基準,則更新緩存。當客戶編寫數據時,服務器必須將請求推遲到每個租約持有人都已批准或租約的期限屆滿爲止。

我們在這裏將自己限制爲直寫式緩存,因爲這樣做簡化了解釋; 直接擴展該機制以支持非直寫式緩存。直寫提供了清晰的失敗語義:不會丟失任何客戶端可見的寫操作; 否則,應用程序必須準備好從丟失的寫操作中恢復。儘管某些人認爲文件高速緩存的直寫成本過高,但是通過對臨時文件進行特殊處理,可以大大降低成本,因爲臨時文件會收到大部分寫操作。

爲了說明使用租用的文件高速緩存的操作,請考慮將無盤工作站用於文檔存儲。工作站首次執行寫操作時,它將在包含待寫的二進制文件上獲得租約,期限爲(例如)10秒。5秒鐘後訪問同一文件的另一個客戶端可以使用此文件的緩存版本,而無需與文件服務器聯繫。10秒期限到期後對該文件的訪問需要緩存與服務器進行檢查。當新的寫操作發生時,寫入將延遲到每個租約持有人都批准了寫入爲止。如果某些持有此文件租約的主機無法訪問,則延遲將持續到租約到期爲止。

在前面的示例中,最常見的讀取和寫入操作不僅限於對文件內容的操作。爲了支持重複打開,高速緩存還必須保存名稱到文件的綁定和權限信息,並且它需要對此信息進行租約才能使用該信息來執行打開操作。同樣,修改此信息(如重命名文件)將構成寫入。

短租期有幾個優點。 一是它們最大程度地減少了由客戶端和服務器故障(以及分區通信故障)導致的延遲。當服務器無法與客戶端通信時,服務器必須延遲對失敗的客戶端持有租約的文件的寫入,直到該租約到期爲止。當服務器崩潰後恢復時,它必須履行崩潰之前授予的租約。如果它記錄已授予租約的最大期限,並且在該期間延遲了對所有文件的寫操作,這很容易做到,從而有效地增加了以最大期限完全恢復的時間。或者,服務器可以在持久性存儲上維護更詳細的租約記錄,但是除非租約的期限比恢復時間長得多,否則額外的I / O流量不太可能是合理的。

短租約還可以最大程度地減少錯誤的寫共享。錯誤共享是指在文件訪問中不存在實際衝突時的租約衝突。從細節上講,當一個客戶端寫入文件時,如果另一個客戶端當前未訪問該文件,則該錯誤被另一個客戶端持有的租約所覆蓋。在沒有租約不會發生衝突的情況下,虛假共享會給租約所有者帶來回調的開銷(從而延遲了請求的客戶端並加載了租約所有者和服務器)。在極端情況下,如果客戶端在另一個客戶端修改文件之前不訪問文件,則租約期限應設爲零。

最後,短租期減少了服務器的存儲需求,因爲可以回收過期租約的記錄。但是,用於跟蹤服務器已授予的租賃的服務器的開銷存儲是適中的。服務器需要記錄每個租賃所有者的身份以及所持有的租賃清單; 每個租約只需要幾個指針。對於擁有約一百份租約的客戶,每個客戶的總租約約爲一千字節。即使這是一個問題,也可以通過以較大的粒度記錄租約來減少租約,從而使每個客戶都持有很少的租約,但會增加競爭。稍後我們將說明如何消除最常見的廣泛共享文件類別的每客戶記錄。

對於客戶端和服務器而言,長期租賃對於重複訪問且寫入共享量相對較小的文件而言,效率顯着提高。

租約的基本概述

通過對論文的閱讀,可以得出大致思路,在分佈式緩存中,還是會有一箇中心化Server幾點保存元數據,客戶端讀取數據的時候會去檢查數據是否在本地緩存中,如果不在本地緩存中則去讀取Server端的數據信息,然後Server會頒發一個過期時間給client,並且客戶端會緩存從Server端獲取到的內容,如果客戶端的緩存是在有效期的緩存時間內的,則客戶端直接讀取數據,否則重新去Server端獲取數據。示例圖如下;

在這裏插入圖片描述

客戶端查詢過程

首先,服務端的架構圖如上所示,初始狀態下,ClientA、ClientB和ClientC都是本地Cache爲空的狀態,假如ClientA需要知道A的值得時候,此時ClientA先檢查本地是否在租期有效期內擁有該值,如果沒有則去Server端獲取,獲取之後的狀態如下所示;

在這裏插入圖片描述

如果ClientA再次需要獲取A的值得時候,假如租約在有效期裏面的,本地就直接去返回A的值爲2,並不會再去請求Server端數據,該整個流程的時序圖如下;

用戶ClientAServer查詢A的值檢查本地緩存是否有值,此時本地緩存沒有向Server端請求A的數據內容返回有關A的值,設置租約時間獲取數據之後,設置數據緩存指定的租約時間返回A的值查詢A的值此時本地緩存中再租約期中有A的值直接返回A的值用戶ClientAServer

大致流程如上圖所示,此時有關本地的緩存值就緩存在了ClientA的本地中,並且設置了一個租約時間,在這個租約時間內,ClientA查詢A的內容的時候,都是直接從本地緩衝中直接返回數據。

客戶端數據修改流程

假如在ClientA和ClientB都是從Server查詢了A的值,此時Server分別頒給了ClientA和ClientB有關A的值得租約,此時系統的狀態如下;

在這裏插入圖片描述

此時ClientC需要修改A的值,根據論文的大致思路,此時Server所做的操作就是先阻塞其他客戶端有關A的值得讀取,然後Server會等待所有客戶端的租約結束,即等待一分鐘之後ClientA和ClientB的租約失效,接着就ClientC修改A的值就會執行成功,此時返回ClientC的值修改成功,此時被阻塞的有關A的數據讀的請求就返回數據,此時ClientA和ClientB如果需要獲取A的值得話,就需要重新向Server端去獲取新的值,此時就獲取的就是ClientC修改的值。該過程的流程圖如下;

用戶ClientCServerClientD修改A的值爲5修改A的值爲5此時Server阻塞有關A的讀請求獲取A的值此時所有客戶端有關A的租約都過期修改A值修改A的值成功A的值爲5用戶ClientCServerClientD

該過程就保證了在客戶端本地緩存值得情況下,保證了數據一致性。這種機制主要就是,Server對數據的處理都是根據對客戶端發放的租約進行控制的,無論客戶端是否收到該租約,服務端只要在租約內都不保證不修改該數據,從而可以使客戶端能夠安全的使用該數據,等到租約到期之後就修改該數據,所有新進來的請求都是獲取該新的數據,從而保持數據的一致性。

總結

本文主要了解了有關租約的基本原理,租約的基本原理就是在分佈式環境下,通過將讀數據緩存在客戶端本地,從而提升讀的性能,減少對遠端元數據服務器的訪問請求,並且在數據一致性上面,採用服務端對數據進行頒發租約的方式,如果客戶端需要元數據服務器修改數據,修改的操作需要等到所有發送給客戶端的租約過期然後再進行數據的修改,從而保證了數據的一致性。在這個過程中,如果客戶端與服務端的時鐘不同步也可能會造成數據不一致的情況,並且元數據服務器也可能存在單點問題,如果前一種問題可能通過額外手段保證時鐘同步並且將服務端的租約設置的比客戶端的租約要長一些都可能降低由時鐘不同步引起的問題,後一個問題可以參考像zookeeper一樣將元數據服務器做成集羣形式對外提供服務。有關該協議的一些其他的優化措施,需要根據具體的場景進行優化,大家有興趣可自行查閱分析。由於本人才疏學淺,如有錯誤請批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章