亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Zeppelin:一個分布式KV存儲平臺之元信息節點

發布時間:2020-08-14 15:07:22 來源:ITPUB博客 閱讀:209 作者:基礎架構和存儲 欄目:數據庫

從Zeppelin:一個分布式KV存儲平臺之概述的介紹中我們知道元信息節點Meta以集群的形式向整個Zeppelin提供元信息的維護和提供服務。可以說Meta集群是Zeppelin的大腦,是所有元信息變化的發起者。每個Meta節點包含一個Floyd實例,從而也是Floyd的一個節點,Meta集群依賴Floyd提供一致性的內容讀寫。本文將從角色、線程模型、數據結構、選主與分布式鎖、集群擴容縮容及成員變化幾個方面詳細介紹,最后總結在Meta節點的設計開發過程中帶來的啟發。

角色

Zeppelin:一個分布式KV存儲平臺之元信息節點

從上圖可以看出Meta集群的中心地位:

  • 向Client及Node Server提供當前的元信息,包括分片副本信息,Meta集群成員信息等;

  • 保持與Node Server的心跳檢測,發現異常時進行切主;

  • 接受并執行運維命令,完成相應的元信息變化,包括擴容、縮容、創建Table、刪除Table等;

線程模型

Zeppelin:一個分布式KV存儲平臺之元信息節點

相對于存儲節點,元信息節點的線程模型比較簡單:

  • 處理請求的Dispatch線程Worker線程

  • 修改Floyd的Update線程,Update線程是唯一的Floyd修改者。所有的元信息修改需求都會通過任務隊列轉交給Update線程。同時為了減輕Floyd的寫入壓力,這里采用了延時批量提交的方式;

  • Condition線程用來等待Offset條件,一些元信息修改操作如SetMaster,擴容及縮容,需要等到分片副本的主從Binlog Offset追齊時才能執行,Meta從與Node之間的心跳中得到Offset信息,Condition線程不斷的檢查主從的Offset差距,僅當追齊時通知Update線程完成對應修改;

  • Cron線程執行定時任務,包括檢查和完成Meta主從切換、檢查Node存活、Follower Meta加載當前元信息、執行數據遷移任務等。

數據結構

為了完成上述任務,Meta節點需要維護一套完整的數據,包括Node節點心跳信息、Node節點Offset信息、分片信息、Meta成員信息、擴容遷移信息等。由于一致性算法本身限制,我們需要盡量降低對Floyd的訪問壓力,因此并不是所有這些數據都需要直接維護在Floyd中。Zeppelin根據數據的重要程度、訪問頻率及是否可恢復進行劃分,僅僅將低頻訪問且不易恢復的數據記錄在Floyd中。

Zeppelin:一個分布式KV存儲平臺之元信息節點

上圖所示是Meta節點所維護數據的數據結構及存儲方式,可以看出,除了一致性庫Floyd中記錄的數據外,Meta還會在內存中維護對應的數據結構,內存數據結構依賴Floyd中的數據,重新組織并提供更方便訪問的接口。從所完成的任務來看,主要包括三個部分:

1,維護和提供集群元信息(Zeppelin Meta Info)

對應內存數據結構InfoStore,InfoStore依賴Floyd中的數據,包括:

  • 當前元信息的版本號Epoch,每次元信息的變化都會對Epoch加一;

  • 數據分片副本的分布及主從信息Tables

  • 存儲節點地址及存活信息Nodes

  • Meta集群自己的成員信息Members

InfoStore重新組織這些數據,對外提供方便的查詢和修改接口;除此之外InfoStore還會維護一些頻繁修改但可以恢復的數據:

  • 存儲節點上次心跳時間:宕機后丟失,可以通過Floyd中的Nodes信息及恢復時的當前時間恢復,注意這里使用恢復時的當前時間相當于延長的存儲節點的存活;

  • 存儲節點的分片Binlog偏移信息:Meta需要這些信息來決定副本的主從切換,宕機恢復后可以從Node的心跳中獲得,這也就要求Node在重新建立心跳連接后的第一個包需要攜帶全量的Binlog偏移信息。

2,擴容縮容相關的遷移信息(Epend Shrink)

對應內存數據結構MigrateRegister,負責遷移過程的注冊和提供,這部分內容將在稍后的集群擴容、縮容章節中詳細介紹。

3,實現Meta集群高可用(Meta High Available)

Meta以集群的方式提供服務,Leader節點完成寫操作,Follower分擔讀壓力,節點之間依賴Floyd保證一致,從而實現Meta集群的高可用。內存數據結構Election負責節點異常時的選主,依賴Floyd提供的Lock接口及其中的Election相關數據。這部分內容將在稍后的選主與分布式鎖章節中詳細介紹。

選主與分布式鎖

Meta集群中的節點分為Leader和Follower兩種角色:

  • 所有的寫操作及心跳都會重定向到Leader,Leader將需要修改Floyd的請求封裝為Task,加入等待隊列,批量延時的寫入Floyd,并更新本地的內存數據結構。

  • Follower定時檢查Floyd中的元信息,如果變化則加載并修改本地內存數據結構,并對外提供元信息的查詢操作。

因此我們需要一種機制來選主,并且每個Leader需要一個定長的租約時間,在租約時間內集群不會選擇其他Meta節點作為新的Leader,相當于犧牲一定的可用性來優化讀性能。選主問題是典型的分布式鎖的應用,獲得分布式鎖的節點即為主。我們認為分布式鎖是由三層相互獨立的問題組成的,如下圖左邊所示,自下而上分別是一致性(Consistency),鎖的實現(Lock)及鎖的使用(Usage of Lock)。其中Consistency是為了高可用,Lock提供了互斥的加鎖的機制,而Usage of Lock部分通常有兩種實現:

  • 嚴謹實現:加鎖時返回Sequence,這個Sequence自增,獲得鎖的節點之后的所有操作的受體都必須檢查這個Sequence以保證操作在鎖的保護中;

  • 簡單實現:節點在嘗試加鎖時需要提供一個時間,鎖服務保證這個時間內不將鎖給其他節點。使用者需要自己保證所有的操作能在這個時間內完成。這個方法雖然不嚴謹但是非常簡單易用,Zeppelin的Meta集群采用的正是這種方式。

Zeppelin:一個分布式KV存儲平臺之元信息節點

如上圖右邊部分顯示了這三部分在Meta中的對應關系:

  • Consistency我們依賴Floyd實現的Raft,同時Raft對外提供了細粒度的鎖接口以及存儲數據的Set、Get接口;

  • 依賴Raft提供的接口,Meta實現了自己的粗粒度鎖Coarse-Lock,簡單的說,通過Set Get接口存儲或查詢當前Leader的地址信息及上次刷新時間;并通過Floyd的細粒度鎖保護互斥的訪問;Leader定時刷新自己的時間,Follower發現Leader超時后取而代之。Coarse-Lock層實現了Meta集群鎖需要的Election。

  • 利用Coarse-Lock,Meta實現了自己的高可用。Cron線程中不斷觸發當前節點檢查并在需要的時候嘗試選主。

這里需要說明的是,相對于Fine-Lock而言,Coarse-Lock加鎖的時間更長,響應的鎖的遷移也會帶來更大的成本。比如主從鏈接的重新建立,任務隊列的丟棄及清空,Meta工作線程的切換等。因此我們希望下層Lock抖動盡量不要影響上層的主從關系,針對這點Meta中設計了如下兩種機制:

  • Meta主從關系與Floyd主從關系解耦,即使Floyd主從變化,依然有可能對上層Meta集群透明;

  • 引入Jeopardy階段,正常運行過程中,Meta會記錄當前的Leader信息,當Floyd由于網絡或節點異常無法服務時,Meta層會進入Jeopardy階段中,Jeopardy使得Meta節點在一定的時間內依然保持主從關系不變。這個時間就是上面提到的為了讀優化給Leader的Lease。之所以能夠這么做,正是由于Zeppline的設計中盡量減少對Meta集群作為中心節點的依賴,從而可以接受Meta集群短時間的不可用。

集群擴容、縮容

Zeppelin作為存儲集群,考慮到資源利用及業務變化,不可避免的需要進行集群的擴容、縮容或平衡操作。下圖是簡單的擴容操作示例,三個存儲節點Node1,Node2,Node3,負責分片P1,P2,P3的九個主從副本。這時Node4加入,需要將P1的Master副本和P3的Slave副本遷移過去。

Zeppelin:一個分布式KV存儲平臺之元信息節點

針對這類問題,主要有如下訴求:

  • 持續時間可能很長,過程中無人工介入;

  • 保證數據正確;

  • 減少線上服務無感知;

  • 不顯著增大Meta負擔,包括資源使用和代碼復雜度;

  • Meta節點異常或網絡異常后可從斷點恢復;

  • 容忍Node狀態變化;

  • 方便暫停、取消,可以獲取狀態及當前進度;

  • 負載均衡

子問題

為了很好的解決這個問題,我們先進行子問題的推導及切割:

  • 擴容、縮容及平衡,其實都是將多個分片從源節點移動到目的節點;

  • 遷移一個分片,可以拆分為增加新的Slave分片,等待數據同步,切換并刪除原分片三個步驟。

方案

Zeppelin:一個分布式KV存儲平臺之元信息節點

上圖所示是Zeppelin的擴容、縮容及平衡機制:

  • 客戶端命令行工具中將擴容(Expand),縮容(Shrink)及平衡(Balance)操作,通過Zeppelin的數據分布算法DPRD轉化為初始狀態(Init State)和一組DIFF集合,每一個DIFF項指定一個分片副本及其要遷移的源節點、目的節點;

  • Init State及DIFF集合傳遞給Meta Leader節點的Migrate Registor模塊,檢查Init State并將DIFF集合寫入Floyd;

  • Cron線程定時獲取一定量的DIFF項,順序執行每個DIFF項;

  • 生成添加新的從副本的UpdateTask1交給Update線程盡快執行,同時設置狀態將該分片緩寫或阻寫;

  • 生成ConditionTask交給Condition線程,ConditionTask中包括一個Offset條件和一個切換副本的UpdateTask2,這個Offset條件通常指源節點和目的節點偏移量一致;

  • Condition線程等待滿足Offset條件后將對應的UpdateTask2交給Update線程盡快執行;

  • 完成必要的狀態改變后,將對應的DIFF項從Register中刪除,并繼續取出新的DIFF執行,直到全部完成。通過這種方式,任何時候Meta節點宕機,新Leader都可以從Floyd中獲得DIFF并繼續操作。

成員變化

通常Meta集群是一個3或5個節點的一致性集群,有時我們需要改變Meta集群的成員,增加、刪除或替換。Meta集群的成員變化依賴下層的Floyd,Floyd提供每次一個節點變化的Membership Change方式,詳細算法見CONSENSUS: BRIDGING THEORY AND PRACTICE。

Floyd的成員變化后,Meta集群對應修改自己的內存數據結構Membership,同時元信息Epoch加一,從而整個集群的Node及Client都能從新拉取的元信息中得知新的Membership。

Lessons We Learn

1,責任分散

將中心節點的責任分散到大量的Node和Client上,從而減輕對中心節點的依賴:

  • 心跳:由Node發起并檢查鏈接狀態;

  • 元信息提供:Node及Client發現主動拉去,而不是由Meta分發。同時Node還會在訪問錯誤節點時,給Client返回kMove消息來幫助Client不通過Meta即可得到部分需要的元信息數據。

2,考慮擴展性時,減少通信次數有時候比優化單次請求處理速度更有效
3,限制資源的線性增長

比如,我們通過批量延遲提交Flody的方法,將一段時間以內的修改操作歸并起來,變成一次對Floyd的訪問。將請求數級別修改頻次變為每秒常數次。

4,故障恢復時的數據恢復

同樣為了減少Floyd的壓力,我們不會將所有數據存儲到Floyd中,那么有些只在內存中維護的數據就需要在服務恢復時恢復出來,恢復時的數據來源可以包括:

  • 持久化數據(盡量少);

  • 外部請求中攜帶,比如Node的Offset信息從心跳中恢復;

  • 估計值,比如Meta中的Node存活時間是直接用恢復的當前時間的;

5,無重試可重入

Meta中的所有操作都是無重試可重入的,指所有步驟的失敗不直接進行重試,而是做一些狀態恢復后丟棄,依賴外部的二次操作來完成,也就要求所有的的操作都是可重入的,這樣做帶來的好處是:

  • 處理清晰簡單,所有發生錯誤的地方可以直接丟棄任務;

  • 上層更好估計操作完成需要的時間,從而向分布式鎖或Node作出時間上的保證。

參考

https://github.com/Qihoo360/zeppelin

https://github.com/PikaLabs/floyd

https://ramcloud.stanford.edu/~ongaro/thesis.pdf

http://baotiao.github.io/2017/09/12/distributed-lock/

http://catkang.github.io/2018/01/07/zeppelin-overview.html

http://catkang.github.io/2018/01/07/zeppelin-overview.html

https://whoiami.github.io/DPRD

原文鏈接:https://mp.weixin.qq.com/s/eCDWqgRG-FmWFkK6cgzm4w

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

容城县| 乃东县| 汉阴县| 拜城县| 汝城县| 凌源市| 藁城市| 毕节市| 长治市| 岐山县| 虎林市| 吴川市| 武功县| 宽城| 清水河县| 祁阳县| 老河口市| 铜川市| 河东区| 广德县| 青阳县| 凤阳县| 义马市| 富蕴县| 灵丘县| 长武县| 沅江市| 寻甸| 洪雅县| 泗洪县| 白水县| 禹州市| 北票市| 乐山市| 左权县| 松滋市| 阜康市| 沁水县| 丰城市| 齐齐哈尔市| 东辽县|