原文網址:Kafka--原理--冪等/事務_IT利刃出鞘的博客-CSDN博客
簡介
本文介紹Kafka的冪等和事務的原理,
Kafka通過冪等和事務這兩個機制保證了精準一次(exactly once),
訊息傳輸保障
一般而言,訊息中間件的訊息傳輸保障有3個層級,分別如下,
- at most once:至多一次,訊息可能會丟失,但絕對不會重復傳輸,
- at least once:最少一次,訊息絕不會丟失,但可能會重復傳輸,
- exactly once:恰好一次,每條訊息肯定會被傳輸一次且僅傳輸一次,
通常情況下,為保證訊息不丟失,kafka 的producer會有重試機制,但重試可能會導致訊息的重復,訊息重復可以在consumer端處理(冪等性處理),Kafka 從 0.11.0.0 版本開始引入了冪等和事務這兩個特性,在producer到broker這個鏈路就支持了冪等(exactly once),
Kafka在0.11.0.0新加的冪等與事務
官網地址:https://kafka.apache.org/documentation/#upgrade_11_exactly_once_semantics

冪等
引入冪等之前
在正常情況下,produce向Broker投遞訊息,broker將訊息追加寫到對應的流(即某一個topic的某一partition)中,并向Producer回傳ACK信號,表示確認收到,
引入冪等性之前

上圖的實作流程是一種理想狀態下的訊息發送情況,但是實際情況中,會出現各種不確定的因素,比如在Producer在發送給Broker的時候出現網路例外,比如以下這種例外情況的出現:

上圖這種情況,當Producer第一次發送訊息給Broker時,Broker將訊息(x2,y2)追加到了訊息流中,但是在回傳Ack信號給Producer時失敗了(比如網路例外) ,此時,Producer端觸發重試機制,將訊息(x2,y2)重新發送給Broker,Broker接收到訊息后,再次將該訊息追加到訊息流中,然后成功回傳Ack信號給Producer,這樣下來,訊息流中就被重復追加了兩條相同的(x2,y2)的訊息,
引入冪等之后
kafka 為實作冪等性,在底層引入了ProducerID和SequenceNumber,
- ProducerID:在每一個新的Producer初始化時,或被分配一個唯一的ProducerID,這個ProducerID對客戶端使用者是不可見的,
- SequenceNumber:對于每個producerID,Producer發送資料的每個Topic和Partition都對應一個從0開始遞增的SequenceNumber值,
資料發送到kafka中會對資料增加Pid 和SequenceId

當ack信號回傳Producer時出現網路例外,通信失敗情況如下:

當producer發送訊息(x2,y2)給broker 時將其追加到訊息流中,此時Broker回傳Ack信號給Producer時,發生例外導致Producer接收Ack信號失敗,對于Producer來說,會觸發重試機制,將訊息(x2,y2)再次發送,由于引入了冪等性,在每條訊息中附帶了PID(ProducerID)和SequenceNumber,相同的PID和SequenceNumber發送給Broker,而之前Broker快取過之前發送的相同的訊息,那么訊息流中訊息就只有一條(x2,y2)不會出現重復發送的情況,
其處理邏輯為:
對于收到的每一條訊息,只有當它的序列號的值(SN_new)比 broker 端中維護的對應的序列號的值(SN_old)大1(即 SN_new = SN_old + 1)時,broker 才會接收它,
- SN_new< SN_old + 1 說明訊息被重復寫入,broker 可以直接將其丟棄,
- SN_new> SN_old + 1 說明中間有資料尚未寫入,出現了亂序,暗示可能有訊息丟失,對應的生產者會拋出 OutOfOrderSequenceException,這個例外是一個嚴重的例外,后續的諸如 send()、beginTransaction()、commitTransaction() 等方法的呼叫都會拋出 IllegalStateException 的例外,
冪等的缺陷
單會話有效
只能實作單會話上的冪等性,不能實作跨會話的冪等性,這里的會話,你可以理解為 Producer 行程的一次運行,當你重啟了 Producer 行程之后,這種冪等性保證就喪失了,
原因:重啟之后標識producer的PID就變化了,導致broker無法根據這個<PID,TP,SEQNUM>條件去去判斷是否重復,
單磁區有效
只能保證單磁區上的冪等性,即一個冪等性 Producer 能夠保證某個主題的一個磁區上不出現重復訊息,它無法實作多個磁區的冪等性,
原因:在某一個partition 上判斷是否重復是通過一個遞增的sequence number,也就是說這個遞增是針對當前特定磁區的,如果你要是發送到其他磁區上去了,那么遞增關系就不存在了,
事務
其他網址
Kafka-事務-解決跨磁區跨會話的問題 - KevinT·Mitnick - 博客園
kafka事務 | muggle
簡介
前邊說過,Kafka 的 Exactly Once 冪等性只能保證單次會話內的精準一次性,不能解決跨會話和跨磁區的問題,
事務保證Kafka在 Exactly Once 語意的基礎上,Producer 和 Consumer 可以跨磁區和會話,要么全部成功,要么全部失敗,
Producer事務
為實作跨磁區跨會話的事務,需要引入一個全域唯一的 Transaction ID,并將 Producer 獲得的 PID 和 Transaction ID 系結,這樣當Producer重啟之后,就可以通過正在運行的 Transaction ID 獲得原來的 PID,
為了管理 Transaction,Kafka引入了一個新的組件 Transaction Coordinator,Producer就是通過 Transaction Coordinator 獲得 Transaction ID 對應的任務狀態,Transaction Coordinator還負責將事務狀態寫入Kafka的一個內部Topic,這樣即使整個服務重啟,由于事務狀態得到保存,進行中的事務狀態可以得到恢復,
Consumer事務
消費者事務的一致性比較弱,只能夠保證消費者消費訊息是精準一次的(有且只有一次),消費者有一個引數 islation.level,這個引數指定的是事務的隔離級別,
它的默認值是 read_uncommitted(未提交讀),意思是消費者可以消費生產者未commit的訊息,當引數設定為 read_committed,則消費者不能消費到生產者未commit的訊息,
事務的使用場景
kafka事務主要是為了保證資料的一致性,現列舉如下幾個場景供讀者參考:
- producer發的多條訊息組成一個事務,這些訊息需要對consumer同時可見或者同時不可見;
- producer可能會給多個topic發送訊息,需要保證訊息要么全部發送成功要么全部發送失敗(操作的原子性);
- 消費者 消費一個topic,然后做處理再發到另一個topic,這個消費和轉發的動作應該在同一事務中;
- 如果下游消費者只有等上游訊息事務提交以后才能讀到,當吞吐量大的時候就會有問題,因此有了 read committed和read uncommitted兩種事務隔離級別
其他網址
kafka的冪等性和事務性_lianchaozhao的博客-CSDN博客
kafka系列之冪等生產者(11)_【CSDN官方推薦】-CSDN博客
kafka--事務和冪等(二)_atarik@163.com-CSDN博客
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/354572.html
標籤:其他
上一篇:【王喆-推薦系統】復習篇-Sparrow的個性化推薦功能
下一篇:Hadoop學習_大資料核心概念
