1. 程式人生 > >基於 raft 協議的 RocketMQ DLedger 多副本日誌複製設計原理

基於 raft 協議的 RocketMQ DLedger 多副本日誌複製設計原理

目錄

  • 1、RocketMQ DLedger 多副本日誌複製流程圖
    • 1.1 RocketMQ DLedger 日誌轉發(append) 請求流程圖
    • 1.2 RocketMQ DLedger 日誌仲裁流程圖
    • 1.3 RocketMQ DLedger 從節點日誌複製流程圖
  • 2、RocketMQ DLedger 多副本日誌複製實現要點
    • 2.1 日誌編號
    • 2.2 追加與提交機制
    • 2.3 日誌一致性如何保證

上一篇 原始碼分析 RocketMQ DLedger(多副本) 之日誌複製(傳播) ,可能有不少讀者朋友們覺得原始碼閱讀較為枯燥,看的有點雲裡霧裡,本篇將首先梳理一下 RocketMQ DLedger 多副本關於日誌複製的三個核心流程圖,然後再思考一下在異常情況下如何保證資料一致性。
@(本節目錄)

1、RocketMQ DLedger 多副本日誌複製流程圖

1.1 RocketMQ DLedger 日誌轉發(append) 請求流程圖

1.2 RocketMQ DLedger 日誌仲裁流程圖

1.3 RocketMQ DLedger 從節點日誌複製流程圖

2、RocketMQ DLedger 多副本日誌複製實現要點


上圖是一個簡易的日誌複製的模型:圖中客戶端向 DLedger 叢集發起一個寫請求,叢集中的 Leader 節點來處理寫請求,首先資料先存入 Leader 節點,然後需要廣播給它的所有從節點,從節點接收到 Leader 節點的資料推送對資料進行儲存,然後向主節點彙報儲存的結果,Leader 節點會對該日誌的儲存結果進行仲裁,如果超過叢集數量的一半都成功儲存了該資料,主節點則向客戶端返回寫入成功,否則向客戶端寫入寫入失敗。

接下來我們來探討日誌複製的核心設計要點。

2.1 日誌編號

為了方便對日誌進行管理與辨別,raft 協議為一條一條的訊息進行編號,每一條訊息達到主節點時會生成一個全域性唯一的遞增號,這樣可以根據日誌序號來快速的判斷資料在主從複製過程中資料是否一致,在 DLedger 的實現中對應 DLedgerMemoryStore 中的 ledgerBeginIndex、ledgerEndIndex,分別表示當前節點最小的日誌序號與最大的日誌序號,下一條日誌的序號為 ledgerEndIndex + 1 。

與日誌序號還與一個概念繫結的比較緊密,即當前的投票輪次。

2.2 追加與提交機制

請思考如下問題,Leader 節點收到客戶端的資料寫入請求後,通過解析請求,提取資料部分,構建日誌物件,並生成日誌序號,用 seq 表示,然後儲存到 Leader 節點中,然後將日誌廣播(推送)到其從節點,由於這個過程中存在網路時延,如果此時客戶端向主節點查詢 seq 的日誌,由於日誌已經儲存在 Leader 節點中了,如果直接返回給客戶端顯然是有問題的,那該如何來避免這種情況的發生呢?

為了解決上述問題,DLedger 的實現(應該也是 raft 協議的一部分)引入了已提交指標(committedIndex)。即當主節點收到客戶端請求時,首先先將資料儲存,但此時資料是未提交的,此過程可以稱之為追加,此時客戶端無法訪問,只有當叢集內超過半數的節點都將日誌追加完成後,才會更新 committedIndex 指標,得以是資料能否客戶端訪問。

一條日誌要能被提交的充分必要條件是日誌得到了叢集內超過半數節點成功追加,才能被認為已提交。

2.3 日誌一致性如何保證

從上文得知,一個擁有3個節點的 DLedger 叢集,只要主節點和其中一個從節點成功追加日誌,則認為已提交,客戶端即可通過主節點訪問。由於部分資料存在延遲,在 DLedger 的實現中,讀寫請求都將由 Leader 節點來負責。那落後的從節點如何再次跟上叢集的步驟呢?

要重新跟上主節點的日誌記錄,首先要知道的是如何判斷從節點已丟失資料呢?

DLedger 的實現思路是,DLedger 會按照日誌序號向從節點源源不斷的轉發日誌,從節點接收後將這些待追加的資料放入一個待寫佇列中。關鍵中的關鍵:從節點並不是從掛起佇列中處理一個一個的追加請求,而是首先查閱從節點當前已追加的最大日誌序號,用 ledgerEndIndex 表示,然後嘗試追加 (ledgerEndIndex + 1)的日誌,用該序號從代寫佇列中查詢,如果該佇列不為空,並且沒有 (ledgerEndIndex + 1)的日誌條目,說明從節點未接收到這條日誌,發生了資料缺失。然後從節點在響應主節點 append 的請求時會告知資料不一致,然後主節點的日誌轉發執行緒其狀態會變更為COMPARE,將向該從節點發送COMPARE命令,用來比較主從節點的資料差異,根據比較的差異重新從主節點同步資料或刪除從節點上多餘的資料,最終達到一致。於此同時,主節點也會對PUSH超時推送的訊息發起重推,盡最大可能幫助從節點及時更新到主節點的資料。

更多問題,`歡迎大家留言與我一起探討。如果覺得文章對自己有些用處的話,麻煩幫忙點個贊,謝謝。


推薦閱讀:RocketMQ 日誌複製系列文章:
1、原始碼分析 RocketMQ DLedger 多副本儲存實現
2、原始碼分析 RocketMQ DLedger(多副本) 之日誌追加流程
3、原始碼分析 RocketMQ DLedger(多副本) 之日誌複製(傳播)


作者介紹:丁威,《RocketMQ技術內幕》作者,RocketMQ 社群佈道師,公眾號:中介軟體興趣圈 維護者,目前已陸續發表原始碼分析Java集合、Java 併發包(JUC)、Netty、Mycat、Dubbo、RocketMQ、Mybatis等原始碼專欄。可以點選連結加入中介軟體知識星球 ,一起探討高併發、分散式服務架構,交流原始碼。

相關推薦

基於 raft 協議RocketMQ DLedger 副本日誌複製設計原理

目錄 1、RocketMQ DLedger 多副本日誌複製流程圖 1.1 RocketMQ DLedger 日誌轉發(append) 請求流程圖 1.2 RocketMQ DLedger 日誌仲裁流程圖 1.

原始碼分析 RocketMQ DLedger(副本) 之日誌複製(傳播)

目錄 1、DLedgerEntryPusher 1.1 核心類圖 1.2 構造方法 1.3 startup 2、EntryDispatcher 詳解 2.1

原始碼分析 RocketMQ DLedger 副本之 Leader 選主

目錄 1、DLedger關於選主的核心類圖 1.1 DLedgerConfig 1.2 MemberState 1.3 raft協議相關 1.4 DLedgerRpcService

DLedger基於 raft 協議的 commitlog 儲存庫

尊敬的阿里雲使用者: 您好!為方便您試用開源 RocketMQ 客戶端訪問阿里雲MQ,我們申請了專門的優惠券,優惠券可以直接抵

RocketMQ 整合 DLedger(副本)即主從切換實現平滑升級的設計技巧

目錄 1、閱讀原始碼之前的思考 2、從 Broker 啟動流程看 DLedger 2.1 構建 DefaultMessageStore 2.2 增加節點狀態變更事件監聽器 2.3 呼叫 Def

Apache Kafka-核心元件和流程-副本管理器-設計-原理(入門教程輕鬆學)

本入門教程,涵蓋Kafka核心內容,通過例項和大量圖表,幫助學習者理解,任何問題歡迎留言。 目錄: 本章簡單介紹了副本管理器,副本管理器負責分割槽及其副本的管理。副本管理器具體的工作流程可以參考牟大恩所著的《Kafka入門與實

RocketMQ 副本前置篇:初探raft協議

目錄 1、Leader選舉 1.1 一輪投票中,只有一個節點發起投票的情況 1.2 一輪投票中,超過一個節點發起投票的情況 1.3 思考如何實現Raft選主 2、日誌複製

RocketMQ 升級到主從切換(DLedger副本)實戰

目錄 1、RocketMQ DLedger 多副本即主從切換核心配置引數詳解 2、搭建主從同步環境 3、主從同步叢集升級到DLedger 3.1 部署架構 3.2 升級步驟 3

基於TCP協議實現Linux下客戶端與伺服器之間的通訊,實現執行緒、程序伺服器

TCP是TCP/IP協議族中一個比較重要的協議,這是一種可靠、建立連結、面向位元組流的傳輸,工作在傳輸層。和TCP相對的不可靠、無連結、面向資料報的協議UDP,瞭解UDP客戶端與伺服器之間通訊請戳UDP協議實現的伺服器與客戶端通訊 TCP協議建立連線 首

SpringBoot整合WebSocket【基於STOMP協議】進行點對點[一對一]和廣播[一對]實時推送,內附簡易聊天室demo

最近專案來了新需求,需要做一個實時推送的功能,伺服器主動推送訊息給客戶端,在網上經過一輪搜查之後,確定使用WebSocket來進行開發。以前經常聽說WebSocket的神奇之處,如今終於可以嘗試使用它了。1.淺談WebSocketWebSocket是在HTML5基礎上單個TC

【Java】基於TCP協議執行緒伺服器-客戶端互動控制檯聊天室簡例

      前兩天想到一個手機APP專案,使用到藍芽,發現BluetoothSocket和J2EE網路變成的Socket差不多,使用之餘順手寫一個多執行緒伺服器與客戶端互動實現聊天室的一個小例子,方便新人學習網路程式設計模組,期間使用到多執行緒和IO輸入輸出流的

linux下C語言程式設計日誌(1):基於TCP協議的伺服器/客戶端程式

  基於TCP協議的伺服器/客戶端程式  首先我們看一下使用TCP協議進行網路通訊的程式基本模型:伺服器首先進行初始化操作:呼叫函式socket建立一個套接字,函式bind將這個套接字與伺服器的公認地址繫結在一起,函式listen將這個套接字換成傾聽套接字,然後呼叫函式acc

基於TCP協議伺服器(執行緒/程序)

基於TCP協議的伺服器,執行緒,多程序版本。 為了解決伺服器可以同時和多個客戶端資料互動。 程式碼如下: server.c #include<stdio.h> #include<stdlib.h> #include<sy

Raft協議詳解(三)日誌複製

在這一部分,我們講Raft幾個子問題中的日誌複製問題。主要內容是講Raft為什麼要進行日誌複製,以及如何進行日誌複製的。日誌複製(log replication)是leader的主要工作之一。在前面的第一、二部分,我們講到了日誌(log)是Raft的一致性保證非

基於Struts2+Hibernate的DetachedCriteria條件查詢

img 類別 ota 配置 his property mat total ide 上一篇我們講訴了基於SSH框架利用Criteria的多條件查詢,這一篇我們就接著來看基於SSH框架利用DetachedCriteria的多條件查詢。 一、Jsp表單查詢頁 1 &

基於TI Davinci架構的核/雙核開發高速掃盲(以OMAP L138為例),dm8168核開發參考以及達芬奇系列資料user guide整理

uwa 全部 dap setting pos eclips develop serial ger 基於TI Davinci架構的雙核嵌入式應用處理器OMAPL138開發入門 原文轉自http://blog.csdn.net/wangpengqi/article/de

Java中基於HTTP協議網絡編程

copy 統一 throws 網絡編程 設置 查詢 trac enc pac java中為我們的網絡支持提供了java.net包,能夠使我們以編程的方式來訪問Web服務功能,這篇博客,就跟大家分享一下。Java中的網絡編程的知識。主要是學習下該java.net包下的

Jmeter對基於websocket協議的壓力測試

等待時間 ads 響應消息 一次 .org 完成 毫秒 新的 字節 Jmeter對基於websocket協議的壓力測試 WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通信(full-duplex)。

基於memcached協議緩存層流量管理工具:Mcrouter

緩存 nginx 峰值 隨著 cached 了解 基於 門戶 use   隨著這次門戶功能改造的深入,對各個功能模塊有了更加深刻的認識,昨天在編碼的過程中看到工程中引用的memcache緩存層流量管理工具:Mcrouter,結合原來了解到的Nginx在這裏對這款Facebo

基於HTTP協議的輕量級開源簡單隊列服務:HTTPSQS[轉]

海量數據 短信 最大 ima 站內搜索 功能 .html 調用 python HTTPSQS(HTTP Simple Queue Service)是一款基於 HTTP GET/POST 協議的輕量級開源簡單消息隊列服務,使用 Tokyo Cabinet 的 B+Tree K