一文看懂 Kafka 事務實現原理!
1 Kafka 的事務 V.S RocketMQ
RocketMQ 事務主要解決問題:確保執行本地事務和發消息這倆操作都成功 / 失敗。RocketMQ 還有事務反查機制兜底,更提高事務執行的成功率和數據一致性。
而 Kafka 事務,是爲確保在一個事務中發送的多條消息,要麼都成功,要麼都失敗。這裏的多條消息不一定在同一個 topic 和 partition,可以是發往多個 topic 和 partition 的消息。當然,你可在 Kafka 事務執行過程中,加入本地事務,來實現和 RocketMQ 事務類似效果,但 Kafka 沒有事務反查機制。
Kafka 這種事務機制,單獨使用場景不多。更多是配合 Kafka 冪等機制,實現 Kafka 的 Exactly Once 語義。這裏 Exactly Once 和一般 MQ 服務水平的 Exactly Once 不同!
1.1 Exactly Once
一般 MQ 服務水平中的,指消息從 Pro 發送到 Broker,Con 再從 Broker 拉消息消費。這過程中,確保每條消息恰好傳輸一次,不重複、不丟棄。
1.2 At Least Once
包括 Kafka 在內的幾個常見 MQ,都只能做到 At Least Once(至少一次),即保證消息不丟,但可能重複,達不到 Exactly Once。
2 Kafka 的 Exactly Once
使用場景:解決流計算中,用 Kafka 作數據源,並將計算結果保存到 Kafka。數據從 Kafka 的某 topic 中消費,在計算集羣中計算,再把計算結果保存在 Kafka 的其他 topic。
這樣的過程中,保證每條消息都被恰好計算一次,確保計算結果正確。
2.1 案例
將所有訂單消息保存在 Kafka 主題 Order,在 Flink 集羣中運行一個計算任務,統計每分鐘的訂單收入,然後把結果保存在另一個 Kafka 主題 Income。
要保證計算結果準確,就要確保無論 Kafka 集羣 or Flink 集羣中任何節點故障,每條消息都只能被計算一次,不能重複計算,否則計算結果就錯。很重要的限制條件:數據須來自 Kafka 且計算結果都保存到 Kafka,纔可應用到 Kafka 的 Excactly Once 機制。
所以 Kafka 的 Exactly Once 是爲解決在 “讀數據 - 計算 - 保存結果” 的計算過程中,數據不重也不丟,並非一般 MQ 消息生產消費過程中的 Exactly Once。
3 Kafka 的事務實現
實現原理和 RocketMQ 事務差不多,都基於兩階段提交。爲解決分佈式事務,Kafka 引入
3.1 事務協調者
在服務端協調整個事務。非獨立進程,而是 Broker 進程的一部分,協調者和分區一樣通過選舉保證 HA。
類似 RocketMQ,Kafka 集羣也有一個特殊的用於記錄事務日誌的 topic,該事務日誌 topic 的實現和普通 topic 一樣,裏面記錄數據類似 “開啓事務”“提交事務” 這樣的事務日誌。日誌 topic 同樣也包含很多分區。
Kafka 集羣中,可存在多個協調者,每個協調者負責管理和使用事務日誌中的幾個分區。就是爲能並行執行多個事務,提升性能。
3.2 Kafka 事務實現流程
開啓事務時,pro 給協調者發請求開啓事務,協調者在事務日誌中記錄下事務 ID。
然後,pro 發消息前,還要給協調者發請求,告知發送的消息屬於哪個主題和分區,這個信息也會被協調者記錄在事務日誌。
接下來,pro 就可像發送普通消息一樣發事務消息,和 RocketMQ 不同在於:
-
RocketMQ 把未提交的事務消息保存在特殊 queue
-
而 Kafka 在處理未提交的事務消息時,和普通消息一樣,直接發給 Broker,保存在這些消息對應的分區中,Kafka 會在客戶端的 Con 中,暫時過濾未提交的事務消息
消息發送完成後,pro 給協調者發送提交或回滾事務的請求,由協調者來開始兩階段提交,完成事務:
-
第一階段,協調者把事務的狀態設置爲 “預提交”,並寫入事務日誌。至此,事務實際上已經成功,無論接下來發生什麼,事務最終都會被提交
-
第二階段,協調者在事務相關的所有分區中,都會寫一條 “事務結束” 的特殊消息,當 Kafka 的消費者,也就是 client,讀到該事務結束的特殊消息後,就可把之前暫時過濾的那些未提交的事務消息,放行給業務代碼消費
-
最後,協調者記錄最後一條事務日誌,標識該事務已結束
3.3 事務執行時序圖
3.4 準備階段
生產者發消息給協調者開啓事務,然後消息發送到每個分區上
3.5 提交階段
生產者發消息給協調者提交事務,協調者給每個分區發一條 “事務結束” 的消息,完成分佈式事務提交。
4 總結
Kafka 基於兩階段提交來實現事務,利用特殊的主題中的隊列和分區來記錄事務日誌。Kafka 直接把消息放到對應業務分區中,配合客戶端過濾,暫時屏蔽進行中的事務消息。
Kafka 的事務則是用於實現它的 Exactly Once 機制,應用於實時計算的場景中。
參考
- https://www.confluent.io/blog/transactions-apache-kafka/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/loipiQeXZZKaKBbOsqXmvQ