• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    您當(dāng)前的位置是:  首頁(yè) > 資訊 > 文章精選 >
     首頁(yè) > 資訊 > 文章精選 >

    分布式鎖在存儲(chǔ)系統(tǒng)中的技術(shù)實(shí)踐

    2020-09-11 11:10:27   作者:圣陶   來(lái)源:CTI論壇   評(píng)論:0  點(diǎn)擊:


     
      1 背景
      針對(duì)共享資源的互斥訪問(wèn)歷來(lái)是很多業(yè)務(wù)系統(tǒng)需要解決的問(wèn)題。在分布式系統(tǒng)中,通常會(huì)采用分布式鎖這一通用型解決方案。本文將就分布式鎖的實(shí)現(xiàn)原理、技術(shù)選型以及阿里云存儲(chǔ)的具體實(shí)踐進(jìn)行論述。
      
      圖1 鎖
      2 從單機(jī)鎖到分布式鎖
      在單機(jī)環(huán)境中,當(dāng)共享資源自身無(wú)法提供互斥能力的時(shí)候,為了防止多線程/多進(jìn)程對(duì)共享資源的同時(shí)讀寫(xiě)訪問(wèn)造成的數(shù)據(jù)破壞,就需要一個(gè)第三方提供的互斥的能力,這里往往是內(nèi)核或者提供互斥能力的類庫(kù),如下圖所示,進(jìn)程首先從內(nèi)核/類庫(kù)獲取一把互斥鎖,拿到鎖的進(jìn)程就可以排他性的訪問(wèn)共享資源。演化到分布式環(huán)境,我們就需要一個(gè)提供同樣功能的分布式服務(wù),不同的機(jī)器通過(guò)該服務(wù)獲取一把鎖,獲取到鎖的機(jī)器就可以排他性的訪問(wèn)共享資源,這樣的服務(wù)我們統(tǒng)稱為分布式鎖服務(wù),鎖也就叫分布式鎖。
     
      圖2 單機(jī)鎖到分布式鎖
      由此抽象一下分布式鎖的概念,首先分布式鎖需要是一個(gè)資源,這個(gè)資源能夠提供并發(fā)控制,并輸出一個(gè)排他性的狀態(tài),也就是:
    • 鎖 = 資源 + 并發(fā)控制 + 所有權(quán)展示
      以常見(jiàn)的單機(jī)鎖為例:
    • Spinlock = BOOL + CAS (樂(lè)觀鎖)
    • Mutex = BOOL + CAS + 通知 (悲觀鎖)
      Spinlock和Mutex都是一個(gè)Bool資源,通過(guò)原子的CAS指令:當(dāng)現(xiàn)在為0設(shè)置為1,成功的話持有鎖,失敗的話不持有鎖,如果不提供所有權(quán)的展示,例如AtomicInteger,也是通過(guò)資源(Interger)+CAS,但是不會(huì)明確的提示所有權(quán),因此不會(huì)被視為一種鎖,當(dāng)然,可以將“所有權(quán)展示”這個(gè)更多地視為某種服務(wù)提供形式的包裝。
      單機(jī)環(huán)境下,內(nèi)核具備“上帝視角”,能夠知道進(jìn)程的存活,當(dāng)進(jìn)程掛掉的時(shí)候可以將該進(jìn)程持有的鎖資源釋放,但發(fā)展到分布式環(huán)境,這就變成了一個(gè)挑戰(zhàn),為了應(yīng)對(duì)各種機(jī)器故障、宕機(jī)等,就需要給鎖提供了一個(gè)新的特性:可用性。
      如下圖所示,任何提供三個(gè)特性的服務(wù)都可以提供分布式鎖的能力,資源可以是文件、KV等,通過(guò)創(chuàng)建文件、KV等原子操作,通過(guò)創(chuàng)建成功的結(jié)果來(lái)表明所有權(quán)的歸屬,同時(shí)通過(guò)TTL或者會(huì)話來(lái)保證鎖的可用性。
     
      圖3 分布式鎖的特性和實(shí)現(xiàn)
      3 分布式鎖的系統(tǒng)分類
      根據(jù)鎖資源本身的安全性,我們將分布式鎖分為兩個(gè)陣營(yíng):
    • A:基于異步復(fù)制的分布式系統(tǒng),例如mysql,tair,redis等;
    • B:基于paxos協(xié)議的分布式一致性系統(tǒng),例如zookeeper,etcd,consul等;
      基于異步復(fù)制的分布式系統(tǒng),存在數(shù)據(jù)丟失(丟鎖)的風(fēng)險(xiǎn),不夠安全,往往通過(guò)TTL的機(jī)制承擔(dān)細(xì)粒度的鎖服務(wù),該系統(tǒng)接入簡(jiǎn)單,適用于對(duì)時(shí)間很敏感,期望設(shè)置一個(gè)較短的有效期,執(zhí)行短期任務(wù),丟鎖對(duì)業(yè)務(wù)影響相對(duì)可控的服務(wù)。
      基于paxos協(xié)議的分布式系統(tǒng),通過(guò)一致性協(xié)議保證數(shù)據(jù)的多副本,數(shù)據(jù)安全性高,往往通過(guò)租約(會(huì)話)的機(jī)制承擔(dān)粗粒度的鎖服務(wù),該系統(tǒng)需要一定的門(mén)檻,適用于對(duì)安全性很敏感,希望長(zhǎng)期持有鎖,不期望發(fā)生丟鎖現(xiàn)象的服務(wù)。
      4 阿里云存儲(chǔ)分布式鎖
      阿里云存儲(chǔ)在長(zhǎng)期的實(shí)踐過(guò)程中,在如何提升分布式鎖使用時(shí)的正確性、保證鎖的可用性以及提升鎖的切換效率方面積累比較多的經(jīng)驗(yàn)。
      4.1 嚴(yán)格互斥性
      互斥性作為分布式鎖最基本的要求,對(duì)用戶而言就是不能出現(xiàn)“一鎖多占”,那么存儲(chǔ)分布式鎖是如何避免該情況的呢?
      答案是,服務(wù)端每把鎖都和唯一的會(huì)話綁定,客戶端通過(guò)定期發(fā)送心跳來(lái)保證會(huì)話的有效性,也就保證了鎖的擁有權(quán)。當(dāng)心跳不能維持時(shí),會(huì)話連同關(guān)聯(lián)的鎖節(jié)點(diǎn)都會(huì)被釋放,鎖節(jié)點(diǎn)就可以被重新?lián)屨肌_@里有一個(gè)關(guān)鍵的地方,就是如何保證客戶端和服務(wù)端的同步,在服務(wù)端會(huì)話過(guò)期的時(shí)候,客戶端也能感知,如下圖所示,在客戶端和服務(wù)端都維護(hù)了會(huì)話的有效期的時(shí)間,客戶端從心跳發(fā)送時(shí)刻(S0)開(kāi)始計(jì)時(shí),服務(wù)端從收到請(qǐng)求(S1)開(kāi)始計(jì)時(shí),這樣就能保證客戶端會(huì)先于服務(wù)端過(guò)期。用戶在創(chuàng)建鎖之后,核心工作線程在進(jìn)行核心操作之前可以判斷是否有足夠的有效期,同時(shí)我們不再依賴墻上時(shí)間,而是基于系統(tǒng)時(shí)鐘來(lái)對(duì)時(shí)間進(jìn)行判斷,系統(tǒng)時(shí)鐘更加精確,且不會(huì)向前或者向后移動(dòng)(秒級(jí)別誤差毫秒級(jí),同時(shí)在NTP跳變的場(chǎng)景,最多會(huì)修改時(shí)鐘的速率)。
     
      圖4 存儲(chǔ)場(chǎng)景的使用方式
      在分布式鎖互斥性上,我們是不是做到完美了?并非如此,還是存在一種情況下業(yè)務(wù)基于分布式鎖服務(wù)的訪問(wèn)互斥會(huì)被破壞。我們來(lái)看下面的例子:如下圖9所示,客戶端在時(shí)間點(diǎn)S0嘗試去搶鎖,在時(shí)間點(diǎn)S1在后端搶鎖成功,因此也產(chǎn)生了一個(gè)分布式鎖的有效期窗口。在有效期內(nèi),時(shí)間點(diǎn)S2做了一個(gè)訪問(wèn)存儲(chǔ)的操作,很快完成,然后在時(shí)間點(diǎn)S3判斷鎖的有效期依舊成立,繼續(xù)執(zhí)行訪問(wèn)存儲(chǔ)操作,結(jié)果這個(gè)操作耗時(shí)良久,超過(guò)了分布式鎖的過(guò)期時(shí)間,那么可能這個(gè)時(shí)候,分布式鎖已經(jīng)被其他客戶端搶占成功,進(jìn)而出現(xiàn)兩個(gè)客戶端同時(shí)操作同一批數(shù)據(jù)的可能性,這種可能性是存在的,雖然概率很小。
     
      圖6 越界場(chǎng)景
      針對(duì)這個(gè)場(chǎng)景,具體的應(yīng)對(duì)方案是在操作數(shù)據(jù)的時(shí)候確保有足夠的鎖有效期窗口,當(dāng)然如果業(yè)務(wù)本身提供回滾機(jī)制的話,那么方案就更加完備,該方案也在存儲(chǔ)產(chǎn)品使用分布式鎖的過(guò)程中被采用。
      還有一個(gè)更佳的方案,即,存儲(chǔ)系統(tǒng)本身引入IO Fence能力。這里就不得不提Martin Kleppmann和redis的作者antirez之間的討論了,redis為了防止異步復(fù)制導(dǎo)致的鎖丟失的問(wèn)題,引入redlock,該方案引入了多數(shù)派的機(jī)制,需要獲得多數(shù)派的鎖,最大程度的保證了可用性和正確性,但仍然有兩個(gè)問(wèn)題:
    • 墻上時(shí)間的不可靠(NTP時(shí)間)
    • 異構(gòu)系統(tǒng)的無(wú)法做到嚴(yán)格正確性
      墻上時(shí)間可以通過(guò)非墻上時(shí)間MonoticTime來(lái)解決(redis目前仍然依賴墻上時(shí)間),但是異構(gòu)系統(tǒng)的只有一個(gè)系統(tǒng)并沒(méi)有辦法保證完全正確,如下圖10所示,Client1獲取了鎖,在操作數(shù)據(jù)的時(shí)候發(fā)生了GC,在GC完成時(shí)候丟失了鎖的所有權(quán),造成了數(shù)據(jù)不一致。
      圖7 異構(gòu)系統(tǒng)無(wú)法做到完全正確性
      因此需要兩個(gè)系統(tǒng)同時(shí)協(xié)作來(lái)完成一個(gè)完全正確的互斥訪問(wèn),在存儲(chǔ)系統(tǒng)引入IO Fence能力,如下圖11所示,全局鎖服務(wù)提供全局自增的token,Client1拿到鎖返回的token是33,并帶入存儲(chǔ)系統(tǒng),發(fā)生GC,當(dāng)Client2搶鎖成功返回34,帶入存儲(chǔ)系統(tǒng),存儲(chǔ)系統(tǒng)會(huì)拒絕token較小的請(qǐng)求,那么經(jīng)過(guò)了長(zhǎng)時(shí)間full gc重新恢復(fù)后的Client 1再次寫(xiě)入數(shù)據(jù)的時(shí)候,因?yàn)榇鎯?chǔ)層記錄的Token已經(jīng)更新,攜帶token值為33的請(qǐng)求將被直接拒絕,從而達(dá)到了數(shù)據(jù)保護(hù)的效果(chubby的論文中有講述,也是Martin Kleppmann提出的解決方案)。
      
      圖8 引入IO Fence能力
      這與阿里云分布式存儲(chǔ)平臺(tái)盤(pán)古的設(shè)計(jì)思路不謀而合,盤(pán)古支持了類似IO Fence的寫(xiě)保護(hù)能力,引入Inline File的文件類型,配合Seal File操作,這就有著類似IO Fence的寫(xiě)保護(hù)能力,首先,SealFile操作用來(lái)關(guān)閉已經(jīng)打開(kāi)的cs上面的文件,防止舊的Owner繼續(xù)寫(xiě)數(shù)據(jù);其次,InlineFile可以防止舊的Owner打開(kāi)新的文件。這兩個(gè)功能事實(shí)上也是提供了存儲(chǔ)系統(tǒng)中的Token支持。
      4.2 可用性
      存儲(chǔ)分布式鎖通過(guò)持續(xù)心跳來(lái)保證鎖的健壯性,讓用戶不用投入很多精力關(guān)注可用性,但也有可能異常的用戶進(jìn)程持續(xù)占據(jù)鎖。針對(duì)該場(chǎng)景,為了保證鎖最終可以被調(diào)度,提供了可以安全釋放鎖的會(huì)話加黑機(jī)制。
      當(dāng)用戶需要將發(fā)生假死的進(jìn)程持有的鎖釋放時(shí),可以通過(guò)查詢會(huì)話信息,并將會(huì)話加黑,此后,心跳將不能正常維護(hù),最終導(dǎo)致會(huì)話過(guò)期,鎖節(jié)點(diǎn)被安全釋放。這里我們不是強(qiáng)制刪除鎖,而是選用禁用心跳的原因如下:
      刪除鎖操作本身不安全,如果鎖已經(jīng)被其他人正常搶占,此時(shí)刪鎖請(qǐng)求會(huì)產(chǎn)生誤刪除。
      b.刪除鎖后,持有鎖的人會(huì)話依然正常,它仍然認(rèn)為自己持有鎖,會(huì)打破鎖的互斥性原則。
      4.3 切換效率
      當(dāng)進(jìn)程持有的鎖需要被重新調(diào)度時(shí),持有者可以主動(dòng)刪除鎖節(jié)點(diǎn),但當(dāng)持有者發(fā)生異常(如進(jìn)程重啟,機(jī)器宕機(jī)等),新的進(jìn)程要重新?lián)屨迹托枰却鹊臅?huì)話過(guò)期后,才有機(jī)會(huì)搶占成功。默認(rèn)情況下,分布式鎖使用的會(huì)話生命期為數(shù)十秒,當(dāng)持有鎖的進(jìn)程意外退出后(未主動(dòng)釋放鎖),最長(zhǎng)需要經(jīng)過(guò)很長(zhǎng)時(shí)間鎖節(jié)點(diǎn)才可以被再次搶占。
     
    期時(shí)間
      要提升切換精度,本質(zhì)上要壓縮會(huì)話生命周期,同時(shí)也意味著更快的心跳頻率,對(duì)后端更大的訪問(wèn)壓力。我們通過(guò)對(duì)進(jìn)行優(yōu)化,使得會(huì)話周期可以進(jìn)一步壓縮。
      同時(shí)結(jié)合具體的業(yè)務(wù)場(chǎng)景,例如守護(hù)進(jìn)程發(fā)現(xiàn)鎖持有進(jìn)程掛掉的場(chǎng)景,提供鎖的CAS釋放操作,使得進(jìn)程可以零等待進(jìn)行搶鎖。比如利用在鎖節(jié)點(diǎn)中存放進(jìn)程的唯一標(biāo)識(shí),強(qiáng)制釋放已經(jīng)不再使用的鎖,并重新?tīng)?zhēng)搶,該方式可以徹底避免進(jìn)程升級(jí)或意外重啟后搶鎖需要的等待時(shí)間。
      5 結(jié)語(yǔ)
      阿里云存儲(chǔ)提供了完整的分布式鎖解決方案,經(jīng)過(guò)了阿里云眾多云產(chǎn)品寶貴的業(yè)務(wù)場(chǎng)景中長(zhǎng)期錘煉,穩(wěn)定高可靠,且提供了多種語(yǔ)言的SDK選擇,甚至是RESTful集成方案。
      分布式鎖提供了分布式環(huán)境下共享資源的互斥訪問(wèn),業(yè)務(wù)或者依賴分布式鎖追求效率提升,或者依賴分布式鎖追求訪問(wèn)的絕對(duì)互斥。同時(shí),在接入分布式鎖服務(wù)過(guò)程中,要考慮接入成本、服務(wù)可靠性、分布式鎖切換精度以及正確性等問(wèn)題,正確和合理的使用分布式鎖,是需要持續(xù)思考并予以優(yōu)化的。
    【免責(zé)聲明】本文僅代表作者本人觀點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對(duì)文中陳述、觀點(diǎn)判斷保持中立,不對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請(qǐng)讀者僅作參考,并請(qǐng)自行承擔(dān)全部責(zé)任。

    相關(guān)熱詞搜索: 阿里云

    上一篇:管理居家辦公員工的三項(xiàng)建議

    下一篇:最后一頁(yè)

    專題

    CTI論壇會(huì)員企業(yè)

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 衢州市| 哈巴河县| 会同县| 股票| 沿河| 土默特左旗| 山丹县| 江孜县| 屯留县| 稻城县| 蒲江县| 县级市| 家居| 石城县| 衡东县| 怀宁县| 台东市| 固原市| 惠水县| 乌兰浩特市| 综艺| 喜德县| 黑龙江省| 拜泉县| 福贡县| 红河县| 桃园市| 舒城县| 徐闻县| 曲麻莱县| 罗源县| 大化| 诸暨市| 昭觉县| 佛学| 清原| 十堰市| 昆明市| 巴彦县| 获嘉县| 门源| http://444 http://444 http://444 http://444 http://444 http://444