訂閱
糾錯
加入自媒體

技術(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í)的好例子。


<上一頁  1  2  
聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

    掃碼關(guān)注公眾號
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯
    x
    *文字標(biāo)題:
    *糾錯內(nèi)容:
    聯(lián)系郵箱:
    *驗(yàn) 證 碼:

    粵公網(wǎng)安備 44030502002758號