技術(shù)文章:分布式系統(tǒng)模式之Consistent Core
尋找 Leader
串行化和線性化
當(dāng) follower 服務(wù)器處理讀取請求時,由于 leader 的最新提交尚未到達(dá)跟隨者,客戶端可能會獲得陳舊數(shù)據(jù)?蛻舳私邮崭碌捻樞蛉员3植蛔,但是更新可能不是最新的。與線性化相對,這是串行化保證。線性化可確保每個客戶端都獲得最新更新。客戶端僅需要讀取元數(shù)據(jù)并且可以暫時容納過時的元數(shù)據(jù)時,便可以使用串行化保證。對于諸如 Lease 之類的操作,需要嚴(yán)格線性化。
如果將 leader 從集群中分割出去,則客戶端可以從 leader 獲得陳舊的值,Raft描述了一種提供線性化讀取的機(jī)制。參見例子etcd 的readIndex實(shí)現(xiàn)。
分割的 follower 可能會發(fā)生類似的情況。follower 可能已分割,可能未將最新值返回給客戶端。為確保 follower 未分割且與 leader 保持最新,他們需要查詢 leader 以了解最新更新,并等到收到最新更新后再對客戶端進(jìn)行響應(yīng),請參閱proposed kafka design例子。
所有操作都必須在 leader 上執(zhí)行,這很重要,因此客戶端庫需要首先找到leader 服務(wù)器。有兩種方法可以滿足此要求。
consistent core中的follower服務(wù)器知道當(dāng)前的 leader,因此,如果客戶端連接到 follower,則它可以返回leader 的地址。然后,客戶端可以直接連接在響應(yīng)中標(biāo)識的 leader。應(yīng)當(dāng)注意,當(dāng)客戶端嘗試連接時,服務(wù)器可能處于leader選舉狀態(tài)。在這種情況下,服務(wù)器無法返回leader地址,客戶端需要等待并嘗試另一臺服務(wù)器。
服務(wù)器可以實(shí)現(xiàn)轉(zhuǎn)發(fā)機(jī)制,并將所有客戶端請求轉(zhuǎn)發(fā)給 leader。這允許客戶端連接到任何服務(wù)器。同樣,如果服務(wù)器處于leader 選舉中,則客戶端需要重試,直到leader選舉成功并建立了合法的 leader 為止。
Zookeeper 和 etcd 之類的產(chǎn)品之所以采用這種方法,是因?yàn)樗鼈冊试Sfollower 服務(wù)器處理一些只讀請求。當(dāng)大量客戶端是只讀客戶端時,這避免了leader 的瓶頸。這樣可以讓客戶端根據(jù)請求類型減少連接到leader 或follower 的復(fù)雜性。
找到leader的一種簡單機(jī)制是嘗試連接到每個服務(wù)器并嘗試發(fā)送請求,如果服務(wù)器不是leader,則服務(wù)器會重定向響應(yīng)。
private void establishConnectionToLeader(List
僅建立TCP連接是不夠的,我們需要知道服務(wù)器是否可以處理我們的請求。因此,客戶端向服務(wù)器發(fā)送一個特殊的連接請求,以確認(rèn)服務(wù)器是否可以處理請求或重定向到 leader 服務(wù)器。
private RequestOrResponse sendConnectRequest(SingleSocketChannel socketChannel) throws IOException {
RequestOrResponse request
= new RequestOrResponse(RequestId.ConnectRequest.getId(), "CONNECT", 0);
try {
return socketChannel.blockingSend(request);
} catch (IOException e) {
resetConnectionToLeader();
throw e;
}
}
如果現(xiàn)有的leader失敗,同樣的技術(shù)被用來從集群中識別新當(dāng)選的 leader。
連接后,客戶端將維護(hù)到leader 服務(wù)器的Single Socket Channel。
處理重復(fù)請求
在失敗的情況下,客戶端可以嘗試連接到新的leader,重新發(fā)送請求。但是,如果那些請求在失敗之前已經(jīng)由失敗的leader 處理過,則可能會導(dǎo)致重復(fù)。因此,在服務(wù)器上具有一種機(jī)制可以忽略重復(fù)的請求,這一點(diǎn)很重要。Idempotent Receiver 模式用于實(shí)現(xiàn)重復(fù)檢測。
使用 Lease 可以完成一組服務(wù)器之間的協(xié)調(diào)任務(wù)?梢允褂孟嗤姆椒▉韺(shí)現(xiàn)組成員身份和故障檢測機(jī)制。
State Watch 用于獲取有關(guān)元數(shù)據(jù)或時間限制租約更改的通知。
例子
眾所周知,谷歌使用[chubby]鎖服務(wù)進(jìn)行協(xié)調(diào)和元數(shù)據(jù)管理。
[kafka]使用[zookeeper]來管理元數(shù)據(jù),并為集群主服務(wù)器做出決策,例如選擇 leader。kafka 提議的體系結(jié)構(gòu)更改將用其自己的基于[raft]的控制器集群代替Zookeeper。
[bookkeeper]使用 Zookeeper 管理集群元數(shù)據(jù)。
[kubernetes]使用[etcd]進(jìn)行協(xié)調(diào),管理集群元數(shù)據(jù)和組成員信息。
[hdfs],[spark],[flink]等所有大數(shù)據(jù)存儲和處理系統(tǒng)都使用[zookeeper]來實(shí)現(xiàn)高可用性和集群協(xié)調(diào)。
說明
注1:因?yàn)檎麄集群都依賴于 Consistent Core,所以了解所使用的一致性算法的細(xì)節(jié)至關(guān)重要。在某些棘手的網(wǎng)絡(luò)分區(qū)情況下,一致性實(shí)現(xiàn)可能會遇到活躍性問題。例如,除非特別注意,否則Raft集群可能會被分割的服務(wù)器破壞,分割的服務(wù)器會不斷觸發(fā)leader選舉。最近在 Cloudflare 發(fā)生的事件是一個值得學(xué)習(xí)的好例子。

最新活動更多
推薦專題
-
10 月之暗面,絕地反擊
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺
- 4 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動駕駛方案解讀
- 9 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?
- 10 封殺AI“照騙”,“淘寶們”終于不忍了?