-
1 # 加米穀大資料
-
2 # WeCoding
一、為什麼只保證單partition有序
如果Kafka要保證多個partition有序,不僅broker儲存的資料要保持順序,消費時也要按序消費。假設partition1堵了,為了有序,那partition2以及後續的分割槽也不能被消費,這種情況下,Kafka 就退化成了單一佇列,毫無併發性可言,極大降低系統性能。因此Kafka使用多partition的概念,並且只保證單partition有序。這樣不同partiiton之間不會干擾對方。
二、Kafka如何保證單partition有序?producer發訊息到佇列時,透過加鎖保證有序。現在假設兩個問題broker leader在給producer傳送ack時,因網路原因超時,那麼Producer 將重試,造成訊息重複。先後兩條訊息傳送。t1時刻msg1傳送失敗,msg2傳送成功,t2時刻msg1重試後傳送成功。造成亂序。2.解決重試機制引起的訊息亂序
為實現Producer的冪等性,Kafka引入了Producer ID(即PID)和Sequence Number。對於每個PID,該Producer傳送訊息的每個<Topic, Partition>都對應一個單調遞增的Sequence Number。同樣,Broker端也會為每個<PID, Topic, Partition>維護一個序號,並且每Commit一條訊息時將其對應序號遞增。對於接收的每條訊息,如果其序號比Broker維護的序號)大一,則Broker會接受它,否則將其丟棄:
如果訊息序號比Broker維護的序號差值比一大,說明中間有資料尚未寫入,即亂序,此時Broker拒絕該訊息,Producer丟擲InvalidSequenceNumber如果訊息序號小於等於Broker維護的序號,說明該訊息已被儲存,即為重複訊息,Broker直接丟棄該訊息,Producer丟擲DuplicateSequenceNumberSender傳送失敗後會重試,這樣可以保證每個訊息都被髮送到broker以上只針對單producer partition的有序保證。0.11版本後,kafka引入事務機制可保證producer掛掉重啟後依然保證有序
-
3 # Java碼農之路
Kafka分散式的單位是partition,同一個partition用一個write ahead log組織,所以可以保證FIFO的順序。不同partition之間不能保證順序。
但是絕大多數使用者都可以透過message key來定義,因為同一個key的message可以保證只發送到同一個partition,比如說key是user id,table row id等等,所以同一個user或者同一個record的訊息永遠只會傳送到同一個partition上,保證了同一個user或record的順序。當然,如果你有key skewness 就有些麻煩,需要特殊處理
回覆列表
關於順序消費的幾點說明:
①、kafka的順序訊息僅僅是透過partitionKey,將某類訊息寫入同一個partition,一個partition只能對應一個消費執行緒,以保證資料有序。
②、除了傳送訊息需要指定partitionKey外,producer和consumer例項化無區別。
那麼如何保證資料的消費?
1、如順序消費中的第①點說明,生產者在寫的時候,可以指定一個 key,比如說我們指定了某個訂單 id 作為 key,那麼這個訂單相關的資料,一定會被分發到同一個 partition 中去,而且這個 partition 中的資料一定是有順序的。
2、消費者從 partition 中取出來資料的時候,也一定是有順序的。到這裡,順序還是 ok 的,沒有錯亂。
3、但是消費者裡可能會有多個執行緒來併發來處理訊息。因為如果消費者是單執行緒消費資料,那麼這個吞吐量太低了。而多個執行緒併發的話,順序可能就亂掉了。
解決方案:
寫N個queue,將具有相同key的資料都儲存在同一個queue,然後對於N個執行緒,每個執行緒分別消費一個queue即可。
注:在單執行緒中,一個 topic,一個 partition,一個 consumer,內部單執行緒消費,這樣的狀態資料消費是有序的。但由於單執行緒吞吐量太低,在資料龐大的實際場景很少採用。
相關:突發宕機,Kafka寫入的資料如何保證不丟失?
https://www.toutiao.com/i6667797088824197644/