java的kafka生產消費
概述
Kafka是一種高吞吐量的分散式釋出訂閱訊息系統,它可以處理消費者在網站中的所有動作流資料。
kafka的相關概念
Broker:Kafka叢集包含一個或多個伺服器,這種伺服器被稱為broker
Topic:每條釋出到Kafka叢集的訊息都有一個類別,這個類別被稱為Topic。(物理上不同Topic的訊息分開儲存,邏輯上一個Topic的訊息雖然儲存於一個或多個broker上但使用者只需指定訊息的Topic即可生產或消費資料而不必關心資料存於何處)
Partition:分割槽Partition是物理上的概念,每個Topic包含一個或多個Partition.建立topic的時候可以指定對應Partition數量
Producer:訊息生產者,負責釋出訊息到Kafka broker
Consumer:訊息消費者,向Kafka broker讀取訊息的客戶端。
Consumer Group:每個Consumer屬於一個特定的Consumer Group(可為每個Consumer指定group name,若不指定group name則屬於預設的group)。
kafka的生產消費流程簡圖:
kafka生產者
kafka生產者是有客戶端實現向kafka服務端寫入檔案的實現。
kafka生產者流程
- 第一步封裝
使用ProducerRecord封裝我們的訊息體成一個record,
在封裝中我們必須要傳入的有:
記錄的訊息體(value),topic。
可選的引數有:
(記錄的時間戳)timestamp、記錄鍵值(key),記錄的請求頭(hearders)
- 第二步 獲取叢集資料元資訊
將topic新增到metadata的topics集合中,獲取叢集中分割槽數cluster.partitionCountForTopic(topic),構建ClusterAndWaitTime物件。
- 第三步 序列化訊息資料
實現序列。Kafka 提供了預設的序列化機制,也支援自定義序列化。
- 第四步 呼叫Partitioner.partition方法選擇合適的分割槽
訊息沒有key則獲取叢集原資料的分割槽後隨機選擇,有key則使用murmur2hash算出分割槽。
- 第五步 訊息放到訊息累加器
分好區的訊息不是直接被髮送到服務端,而是放入了生產者的一個快取裡面。在這個快取裡面,多條訊息會被封裝成為一個批次(batch),每一個分割槽裡的資料有序的,預設一個批次的大小是 16K。
- 第六步 喚醒sender傳送執行緒
返回的結果RecordAppendResult的 if (result.batchIsFull || result.newBatchCreated)則喚醒sender執行緒。
- 第七步:Sender 執行緒把一個一個批次傳送到服務端。
生產者流程圖如下:
kafka消費者
kafka中的消費者和消費者組
消費者
在java中通常用一個消費執行緒來表示。一個分割槽對應一個消費執行緒。一個分割槽的資料只能被 同一個消費組內 的一個 消費者
消費,而 不能拆給同一個消費者組多個消費者 消費。當其中某一些消費者離開或者的時候,就會進行Partition Rebalance分割槽再均衡,使partition的所有權在消費者之間轉移。
消費者組
消費者組是一組消費者的集合。消費者用一個消費者組名錶示自己在哪一個消費者組。每個topic中的資料
可以被 多個 消費者
消費,但是每個消費者組
消費的資料是 互不干擾 的。所以說,每個 消費組
消費的都是完整的資料。
以下是消費者和分割槽的個數消費關係圖:
kafka的消費這的負載均衡演算法
1. A=(partition數量/同組內消費者總個數)
2. M=對上面所得到的A值小數點第一位向上取整
3. 計算出該消費者拉取資料的patition合集:Ci = [P(M*i )~P((i + 1) * M -1)]
假設有一個topic有十個pitition。三個消費者。則計算結果為:
A=10/3 = 3.333
M = 4
C0 = [p(0*4),p(0+1)*4-1] = [p0,p3]
C1 = [p(1*4),p(1+1)*4-1] = [p4,p7]
C2 = [p(2*4),p(2+1)*4-1] = [p8,p11]
所以最終的結果是消費者0消費 p0~p3四個分割槽。;消費者1消費 p4~p7四個分割槽;消費者2消費 p8~p10三個分割槽。
消費者提交偏移量
消費者需要向kafka服務端提交自己的位移資料,告訴服務端自己已經處理到了那個位置的資料。消費者通過_consumer_offset 的特殊主題傳送 訊息,訊息裡包含每個分割槽的偏移量。 偏移量的提交不會影響最新的資料的消費,應為服務端自己也維護了一個每個partition的位置。兩者在所有消費者正常的情況下不會相互影響。所以消費者一直處於執行狀態,偏移量就沒有 什麼用處。不過,如果消費者發生崩潰、有新的消費者加入群組或者停止後從新消費,就會觸發再均衡,再均衡會給每個消費者分配新的分割槽,而不一定是之前處理的那個。為了能夠繼續 之前的工作,消費者需要讀取每個分割槽最後一次提交 的偏移量,然後從偏移量指定的地方 繼續處理。
自動提交偏移量
自動提交偏移量是在每次消費資料的時候,自動提交上一次消費的記錄。自動體積可以通過設定 enable.auto.commit 為 true,這樣Kafka 會在開始呼叫 poll 方法時,提交上次 poll 返回的所有訊息。從順序上來說,poll 方法的邏輯是先提交上一批訊息的位移,再處理下一批訊息,因此它能保證不出現消費丟失的情況。在預設情況下,Consumer 每 5 秒自動提交一次位移。可以通過修改 auto.commit.interval.ms 的值來改變提交頻率。
自動提交位移雖然能保證所有的資料都能被消費和處理。但是可能會出現重複消費。如果消費者在還沒有提交偏移量的時候就發生崩潰,那就會導致下一次從新消費的時候會消費到部分崩潰之前以及消費的資料。
手動提交偏移量
把 auto.commit.offset 設為 false
,讓應用程式決定何時提交偏移量。手動提交偏移量分為兩種,一種是同步提交,一種是非同步提交。一般情況下是兩種混合使用。
同步提交偏移量commitSync()
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
process(records); // 處理訊息
try {
consumer.commitSync(); //提交偏移量
} catch (CommitFailedException e) {
}
}
commitSync() 將會提交由 poll() 返回的最新偏移量 , 所以在處理完所有記錄後要 確保呼叫了 commitSync()。否則還是會有丟失訊息的風險。但是再均衡會導致最近一 批訊息到發生再均衡之間的所有訊息都將被重複處理。在成功提交或碰到無怯恢復的錯誤之前, commitSync() 會一直重試(應用程式也一直阻塞)。
非同步提交偏移量commitAsync()
同步提交的操作,在提交偏移量和處理資料是單執行緒的,所以放入鍋服務端還沒有返回訊息,那麼麼所有的資料消費和處理都會被阻塞掉。這樣就會影響程式的吞吐量。通過一部提交偏移量來降低提交頻率來提升吞吐量,但如果發生了再均衡, 會增加重複訊息的數量。使用非同步提交 API。我們只管傳送提交請求,無需等待 broker的響應。
while (true) {
ConsumerRecords<String, String> records =
consumer.poll(Duration.ofSeconds(1));
process(records); // 處理訊息
try {
consumer.commitAsync(); //非同步提交
} catch (CommitFailedException e) {
}
}
commitAsync()t提交在出現問題時它不會自動重試。因為它是非同步操作,倘若提交失敗後自動重試,那麼它重試時提交的位移值可能早已經“過期”或不是最新值了。
參考文件:
http://kafka.apache.org/10/documentation.html
https://baijiahao.baidu.com/s?id=1658221660132943620&wfr=spider&for=pc
https://www.jianshu.com/p/6845469d99e6
相關文章
- Kafka 架構圖-輕鬆理解 kafka 生產消費Kafka架構
- 插曲:Kafka的生產者案例和消費者原理解析Kafka
- Kafka生產消費資料丟失和優化小結Kafka優化
- 「Kafka應用」PHP實現生產者與消費者KafkaPHP
- kafka_2.11-0.10.2.1 的生產者 消費者的示例(new producer api)KafkaAPI
- Java實現生產者和消費者Java
- SpringBoot整合Kafka(生產者和消費者都是SpringBoot服務)Spring BootKafka
- java編寫生產者/消費者模式的程式。Java模式
- 生產消費問題
- 生產者消費者
- 生產消費者模式模式
- java多執行緒之消費生產模型Java執行緒模型
- java實現生產者消費者問題Java
- 食堂中的生產-消費模型模型
- kafka消費Kafka
- kafka消費者消費訊息的流程Kafka
- kafka生產者和消費者吞吐量測試-kafka 商業環境實戰Kafka
- Java多執行緒——生產者消費者示例Java執行緒
- 生產者消費者模式模式
- 生產者消費者模型模型
- edenhill/kcat:通用命令列非 JVM Apache Kafka 生產者和消費者命令列JVMApacheKafka
- Java多執行緒——消費者與生產者的關係Java執行緒
- Kafka 消費組消費者分配策略Kafka
- Spark Streaming 生產、消費流程梳理Spark
- python 生產者消費者模式Python模式
- Kafka 消費者解析Kafka
- Kafka java api-生產者程式碼KafkaJavaAPI
- RocketMQ系列(三)訊息的生產與消費MQ
- 生產消費實現-寫程式碼
- 九、生產者與消費者模式模式
- 生產者與消費者問題
- ActiveMQ 生產者和消費者demoMQ
- 【Java面試】Kafka 怎麼避免重複消費Java面試Kafka
- 生產者消費者模式--java多執行緒同步方法的應用模式Java執行緒
- Java 多執行緒基礎(十二)生產者與消費者Java執行緒
- 【java併發程式設計】Lock & Condition 協調同步生產消費Java程式設計
- java進階(40)--wait與notify(生產者與消費者模式)JavaAI模式
- flink連線消費kafkaKafka