天天看點

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

  • 消息中間件的應用場景
  • 主流 MQ 架構及對比
    • 說明
    • Kafka 優點
    • Kafka 缺點
    • RocketMQ
    • Pulsar
    • 發展趨勢
  • 各公司發展
  • Kafka
    • Kafka 是什麼?
    • Kafka 術語
    • Kafka 如何持久化?
    • Kafka 檔案存儲機制
    • 分區
      • 為什麼分區?
      • 分區政策?
    • Kafka 是否會消息丢失?
    • 控制器
      • 控制器如何選舉?
      • 控制器有什麼用?
      • 控制器故障轉移
    • Kafka 的 ZooKeeper 存儲結構
  • 分布式事務的應用場景
    • 兩階段最終一緻
    • 如何保證最終一緻?
    • 消息發送的一緻性如何保證?
    • 發送異常會如何?
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

消息中間件的應用場景

  • 異步解耦
  • 削峰填谷
  • 順序收發
  • 分布式事務一緻性

騰訊應用案例:

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

主流 MQ 架構及對比

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

說明

  • Kafka:整個行業應用廣泛
  • RocketMQ:阿裡,從 apache 孵化
  • Pulsar:雅虎開源,符合雲原生架構的消息隊列,社群活躍
  • RabbitMQ 架構比較老,AMQP并沒有在主流的 MQ 得到支援
  • NSQ:記憶體型,不是最優選擇
  • ActiveMQ、ZeroMQ 可忽略

Kafka 優點

  • 非常成熟,生态豐富,與 Hadoop 連接配接緊密
  • 吞吐非常高,可用性高
    • sharding
    • 提升 replication 速度
  • 主要功能:pub-sub,壓縮支援良好
  • 可按照 at least once, at most once 進行配置使用,exactly once 需要 Consumer 配合
  • 叢集部署簡單,但 controller 邏輯很複雜,實作partition 的多副本、資料一緻性
  • controller 依賴 ZooKeeper
  • 異步刷磁盤(除了錢的業務,很少有同步 flush 的需求)

Kafka 缺點

  • 寫入延時穩定性問題,partition 很多時
    • Kafka 通常用機械盤,随機寫造成吞吐下降和延時上升
    • 100ms ~ 500ms
  • 運維的複雜性
    • 單機故障後補充副本
    • 資料遷移
    • 快手的優化:遷移 partition 時舊資料不動,新資料寫入新 partition 一定時間後直接切換

RocketMQ

  • 阿裡根據 Kafka 改造适應電商等線上業務場景
  • 以犧牲性能為代價增強功能
    • 按 key 對消息查詢,維護 hash 表,影響 io
    • 為了在多 shard 場景下保證寫入延遲穩定,在 broker 級别将所有 shard 目前寫入的資料放入一個檔案,形成 commitlog list,放若幹個 index 檔案維護邏輯 topic 資訊,造成更多的随機讀
  • 沒有中心管理節點,現在看起來并沒有什麼用,中繼資料并不多
  • 高精度的延遲消息(快手已支援秒級精度的延遲消息)

Pulsar

  • 存儲、計算分離,友善擴容
    • 存儲:bookkeeper
    • MQ邏輯:無狀态的 broker 處理

發展趨勢

  • 雲原生
  • 批流一體:跑任務時,需要先把 Kafka 資料→HDFS,資源消耗大。如果本來就存在 HDFS,能節省很大資源
  • Serverless

各公司發展

  • 快手:Kafka
    • 所有場景均在使用
    • 特殊形态的讀寫分離
      • 資料實時消費到 HDFS
      • 在有明顯 lag 的 consumer 讀取時,broker 把請求從本地磁盤轉發的 HDFS
      • 不會因為有 lag 的 consumer 對日常讀寫造成明顯的磁盤随機讀寫
    • 由于自己改造,社群新功能引入困難
  • 阿裡巴巴:開源 RocketMQ
  • 位元組跳動
    • 線上場景:NSQ→RocketMQ
    • 離線場景:Kafka→自研的存儲計算分類的 BMQ(協定層直接相容Kafka,使用者可以不換 client)
  • 百度:自研的 BigPipe,不怎麼樣
  • 美團:Kafka 架構基礎上用 Java 進行重構,内部叫 Mafka
  • 騰訊:部分使用了自研的 PhxQueue,底層是 KV 系統
  • 滴滴:DDMQ
    • 對 RocketMQ 和 Kafka 進行封裝
    • 多機房資料一緻性可能有問題
  • 小米:自研 Talos
    • 架構類似 pulsar,存儲是 HDFS,讀場景有優化

Kafka

  • Kafka官網:https://kafka.apache.org/documentation/#uses
  • 最新版本:2.7

Kafka 是什麼?

  • 開源的消息引擎系統(消息隊列/消息中間件)
  • 分布式流處理平台
  • 釋出/訂閱模型
  • 削峰填谷

Kafka 術語

  • Topic:釋出訂閱的主題
  • Producer:向Topic釋出消息的用戶端
  • Consumer:消費者
  • Consumer Group:消費者組,多個消費者共同組成一個組
  • Broker:Kafka的服務程序
  • Replication:備份,相同資料拷貝到多台機器
    • Leader Replica
    • Follower Replica,不與外界互動
  • Partition:分區,解決伸縮性問題,多個Partition組成一個Topic
  • Segment:partition 由多個 segment 組成

Kafka 如何持久化?

  • 消息日志(Log)儲存資料,磁盤追加寫(Append-only)
    • 避免緩慢的随機I/O操作
    • 高吞吐
  • 定期删除消息(日志段)
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

Kafka 檔案存儲機制

https://www.open-open.com/lib/view/open1421150566328.html

  • 每個 partition 相當于一個巨型檔案→多個大小相等 segment 資料檔案中
  • 每個 partition 隻需要順序讀寫就行了,segment 檔案生命周期由配置決定
  • segment file 組成:
    • index file:索引檔案
    • data file:資料檔案
  • segment file 檔案命名規則:
    • 全局第一個 segment 是 0
    • 後序每個加上全局 partition 的最大 offset
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

一對 segment file

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

message 實體結構

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

分區

為什麼分區?

  • Kafka的消息組織方式:主題-分區-消息
  • 一條消息,僅存在某一個分區中
  • 提高伸縮性,不同分區可以放到不同機器,讀寫操作也是以分區粒度

分區政策?

  • 輪詢
  • 随機
  • 按 key 保序,單分區有序
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

Kafka 是否會消息丢失?

  • 隻對“已送出”的消息做有限度的持久化保證
    • 已送出的消息:消息寫入日志檔案
    • 有限度的持久化保證:N個 broker 至少一個存活
  • 生産者丢失資料
    • producer.send(msg) 異步發送消息,不保證資料到達Kafka
    • producer.send(msg, callback) 判斷回調
  • 消費者程式丢失資料
    • 應該「先消費消息,後更新位移的順序」
    • 新問題:消息的重複處理
    • 多線程異步處理消息,Consumer不要開啟自動送出位移,應用程式手動送出位移

控制器

  • 在 ZooKeeper幫助下管理和協調整個 Kafka 叢集
  • 運作過程中,隻能有一個 Broker 成為控制器

控制器如何選舉?

在 ZooKeeper 建立 /controller 節點,第一個建立成功的 Broker 被指定為控制器。

控制器有什麼用?

  • 主題管理(建立、删除、增加分區)
  • 分區重配置設定
  • 上司者選舉
  • 叢集成員管理(新增 Broker、Broker 主動關閉、Broker 當機)(ZooKeeper 臨時節點)
  • 資料服務:最全的叢集中繼資料資訊

控制器故障轉移

  • 隻有一個 Broker 當控制器,單點失效,立即啟用備用控制器
30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

Kafka 的 ZooKeeper 存儲結構

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

分布式事務的應用場景

  • 團隊内部,某些操作要同時更新多個資料源
  • 業務團隊 A 完成某個操作後,B 業務的某個操作也必須完成,A 業務并不能直接通路 B 的資料庫
  • 公司之間,使用者付款後,支付系統(支付寶/微信)必須通知商家的系統更新訂單狀态

兩階段最終一緻

  • 先完成資料源 A 的事務(一階段)
  • 成功後通過某種機制,保證資料源 B 的事務(二階段)也一定最終完成
    • 不成功,會不斷重試直到成功為止
    • 或達到一定重試次數後停止(配合對賬、人工處理)

如何保證最終一緻?

為了保證最終一緻,消息系統和業務程式需要保證:

  • 消息發送的一緻性:消息發送時,一階段事務和消息發送必須同時成功或失敗
  • 消息存儲不丢失:消息發送成功後,到消息被成功消費前,消息伺服器(broker)必須存儲好消息,保證發生故障時,消息不丢失
  • 消費者不丢失消息:處理失敗不丢棄,重試直到成功為止

消息發送的一緻性如何保證?

30分鐘帶你了解「消息中間件」Kafka、RocketMQ消息中間件的應用場景主流 MQ 架構及對比各公司發展Kafka分布式事務的應用場景代碼、思維導圖筆記下載下傳

目标

:本地事務、消息發送必須同時成功/失敗

問題

  • 先執行本地事務,再發送消息,消息可能發送失敗
  • 可把失敗的消息放入記憶體,稍後重試,但成功率也無法達到 100%

解決方案`* 先發送半消息(Half Msg,類似 Prepare 操作),不會投遞給消費者

  • 半消息發送成功,再執行 DB 操作
  • DB 操作執行成功後,送出半消息

發送異常會如何?

  • 1 異常,半消息發送失敗,本地 DB 沒有執行,整個操作失敗,DB/消息的狀态一緻(都沒有送出)
  • 2 異常/逾時
    • 生産者以為失敗了,不執行 DB
    • broker 存儲半消息成功,等不到後序操作,會詢問生産者是送出還是復原(第6步)
  • 3 DB操作失敗:生産者在第 4 步告知 broker 復原半消息
  • 4 送出/復原半消息失敗:broker 等不到這個操作,觸發回查(第 6 步)
  • 5、6、7回查失敗:RocketMQ 最多回查 15 次

代碼、思維導圖筆記下載下傳

代碼和思維導圖在 GitHub 項目中,歡迎大家 star!