Generation Clock模式解決方案
作者: Unmesh Joshi
譯者: java達(dá)人
一個單調(diào)遞增的數(shù)字,表示服務(wù)器的generation 。
問題
在領(lǐng)導(dǎo)者和追隨者設(shè)置中,有可能會出現(xiàn)領(lǐng)導(dǎo)者與追隨者暫時斷開聯(lián)系的情況。leader進(jìn)程中可能會出現(xiàn)垃圾收集暫停,或者暫時的網(wǎng)絡(luò)中斷,導(dǎo)致leader和follower之間的連接斷開。在這種情況下,領(lǐng)導(dǎo)者進(jìn)程仍在運行,在暫停或網(wǎng)絡(luò)中斷結(jié)束后,它將嘗試向追隨者發(fā)送復(fù)制請求。這很危險,因為集群的其他部分可能已經(jīng)選擇了新的leader并接受了來自客戶機的請求。對于集群的其他部分來說,檢測來自舊leader的任何請求非常重要。舊的leader本身也應(yīng)該能夠檢測到它暫時與集群斷開了連接,并采取必要的糾正措施放棄領(lǐng)導(dǎo)者身份。
解決方案
Generation Clock模式是Lamport時間戳的一個示例:這是一種簡單的技術(shù),用于確定跨一組進(jìn)程的事件順序,而不依賴于系統(tǒng)時鐘。每個進(jìn)程維護(hù)一個整數(shù)計數(shù)器,該計數(shù)器在該進(jìn)程執(zhí)行每個操作后遞增。每個進(jìn)程還將這個整數(shù)連同進(jìn)程交換的消息一起發(fā)送給其他進(jìn)程。接收消息的進(jìn)程通過獲取自己的計數(shù)器和消息的整數(shù)值之間的最大值來設(shè)置自己的整數(shù)計數(shù)器。這樣,任何進(jìn)程都可以通過比較相關(guān)的整數(shù)來確定哪個操作在另一個操作之前發(fā)生。如果消息在多個進(jìn)程之間交換,也可以對多個進(jìn)程之間的操作進(jìn)行比較。可以這樣比較的行為被稱為“因果關(guān)系”。
維護(hù)一個單調(diào)遞增的數(shù)字表示服務(wù)器的generation 。每次新領(lǐng)導(dǎo)者選舉時,都應(yīng)該以增加一個generation 為標(biāo)志。generation 需要在服務(wù)器重新啟動之后可用,因此它與 Write-Ahead Log中的每個條目一起存儲。正如在High-Water Mark中所討論的,追隨者使用此信息來查找日志中的沖突條目。
在啟動時,服務(wù)器從日志中讀取最近已知generation 。
class ReplicationModule… this.replicationState = new ReplicationState(config, wal.getLastLogEntryGeneration());
有了領(lǐng)導(dǎo)者和追隨者,服務(wù)器就會在每次有新的領(lǐng)導(dǎo)者選舉時遞增generation 。
class ReplicationModule… private void startLeaderElection() { replicationState.setGeneration(replicationState.getGeneration() + 1); registerSelfVote(); requestVoteFrom(followers); }
服務(wù)器將生成的generation 作為投票請求的一部分發(fā)送到其他服務(wù)器。這樣,在一個成功的領(lǐng)導(dǎo)者選舉后,所有的服務(wù)器都有相同的generation。一旦領(lǐng)導(dǎo)被選出來,追隨者們就會被告知新generation 的情況
follower (class ReplicationModule...) private void becomeFollower(Long generation) { replicationState.setGeneration(generation); transitionTo(ServerRole.FOLLOWING); }
之后,領(lǐng)導(dǎo)者在發(fā)送給追隨者的每個請求中都包含了generation。它將generation包含在每個心跳消息以及發(fā)送給追隨者的復(fù)制請求中。
Leader在其Write-Ahead Log中保留每一個條目的generation
leader (class ReplicationModule...) Long appendToLocalLog(byte[] data) { var logEntryId = wal.getLastLogEntryId() + 1; var logEntry = new WALEntry(logEntryId, data, EntryType.DATA, replicationState.getGeneration()); return wal.writeEntry(logEntry); }
這樣,作為Leader和follower復(fù)制機制的一部分,它也被持久化到follower日志中
如果一個追隨者從一個被廢棄的領(lǐng)導(dǎo)者那里得到一個信息,這個追隨者可以辨別出來,因為它的generation 太小了。追隨者然后返回一個失敗的響應(yīng)。
follower (class ReplicationModule...) Long currentGeneration = replicationState.getGeneration(); if (currentGeneration > replicationRequest.getGeneration()) { return new ReplicationResponse(FAILED, serverId(), currentGeneration, wal.getLastLogEntryId()); }
當(dāng)一個領(lǐng)導(dǎo)者得到這樣一個失敗的響應(yīng)時,他就變成了一個跟隨者,并期待來自新領(lǐng)導(dǎo)者的交流。
Old leader (class ReplicationModule...) if (!response.isSucceeded()) { stepDownIfHigherGenerationResponse(response); return; }
private void stepDownIfHigherGenerationResponse(ReplicationResponse replicationResponse) { if (replicationResponse.getGeneration() > replicationState.getGeneration()) { becomeFollower(replicationResponse.getGeneration()); } }
考慮下面的例子。在三個服務(wù)器集群中,leader1是現(xiàn)有的leader。集群中的所有服務(wù)器的generation都為1。Leader1向追隨者發(fā)送連續(xù)的心跳。Leader1有一個很長的垃圾收集暫停時間,比如5秒。追隨者沒有得到一個心跳,超時后選舉一個新的領(lǐng)導(dǎo)者。新領(lǐng)導(dǎo)者將generation增加到2。垃圾收集暫停結(jié)束后,leader1繼續(xù)向其他服務(wù)器發(fā)送請求。generation為2的追隨者和新領(lǐng)導(dǎo)者拒絕請求,并發(fā)送失敗響應(yīng),帶上generation2。leader1處理失敗響應(yīng),并回退做一個跟隨者,generation 更新為2。


例子
Raft Raft使用Term的概念來標(biāo)記leader generation。
Zab 在Zookeeper中,epoch號作為每個事務(wù)id的一部分進(jìn)行維護(hù)。因此,在Zookeeper中持久化的每個事務(wù)都有一個以epoch標(biāo)記的generation。
Cassandra 在Cassandra中,每個服務(wù)器存儲一個generation編號,該編號在服務(wù)器每次重啟時遞增。generation信息保存在系統(tǒng)密鑰空間中,并作為gossip消息的一部分傳播到其他服務(wù)器。接收到gossip消息的服務(wù)器可以比較它所知道的generation值和gossip消息中的generation值。如果gossip消息中的generation值較高,則知道服務(wù)器已重啟,然后丟棄為該服務(wù)器維護(hù)的所有狀態(tài),并請求新的狀態(tài)。
Kafka中的Epoch 在Kafka中,每次為Kafka集群選擇一個新控制器時,都會創(chuàng)建一個epoch數(shù)并存儲在Zookeeper中。epoch包含在從控制器發(fā)送到集群中其他服務(wù)器的每個請求中。另一個稱為LeaderEpoch的epoch被維護(hù),以了解追隨者分區(qū)High-Water Mark是否落后。
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-5.20立即下載>> 【限時免費】物理場仿真助力生物醫(yī)學(xué)領(lǐng)域技術(shù)創(chuàng)新
-
精彩回顧立即查看>> 【直播】 智測未來·2026海克斯康春季產(chǎn)品創(chuàng)新日
-
精彩回顧立即查看>> 【線下論壇】新唐科技×芯唐南京 2026 年度研討會
-
精彩回顧立即查看>> OFweek 2026(第十五屆)中國機器人產(chǎn)業(yè)大會
-
精彩回顧立即查看>> 維科杯· OFweek 2025中國機器人行業(yè)年度評選
-
精彩回顧立即查看>> 【在線會議】液冷服務(wù)器信號完整性及冷卻液關(guān)鍵電參數(shù)測試
推薦專題
- 1 AI狂歡遇上油價破百,全球股市還能漲多久? | 產(chǎn)聯(lián)看全球
- 2 OpenAI深夜王炸!ChatGPT Images 2.0實測:中文穩(wěn)、細(xì)節(jié)炸,設(shè)計師慌了
- 3 6000億美元估值錨定:字節(jié)跳動的“去單一化”突圍與估值重構(gòu)
- 4 Tesla AI5芯片最新進(jìn)展總結(jié)
- 5 連夜測了一波DeepSeek-V4,我發(fā)現(xiàn)它可能只剩“審美”這個短板了
- 6 熱點丨AI“瑜亮之爭”:既生OpenClaw,何生Hermes?
- 7 AI界的殺豬盤:9秒刪庫跑路,全員被封號,還繼續(xù)扣錢!
- 8 2026,人形機器人只贏了面子
- 9 DeepSeek降價90%:價格屠夫不是身份,是戰(zhàn)略
- 10 AI Infra產(chǎn)業(yè)鏈卡在哪里了?
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市


分享













