Kafka的基本架構(gòu)
Producer:生產(chǎn)者憾儒,也就是發(fā)送消息的一方。生產(chǎn)者負責創(chuàng)建消息乃沙,然后將其發(fā)送到 Kafka起趾。
Consumer:消費者,也就是接受消息的一方警儒。消費者連接到 Kafka 上并接收消息训裆,進而進行相應的業(yè)務邏輯處理。
Consumer Group:一個消費者組可以包含一個或多個消費者蜀铲。使用多分區(qū) + 多消費者方式可以極大提高數(shù)據(jù)下游的處理速度边琉,同一消費組中的消費者不會重復消費消息,同樣的记劝,不同消費組中的消費者消息消息時互不影響变姨。Kafka 就是通過消費組的方式來實現(xiàn)消息 P2P 模式和廣播模式。
Broker:服務代理節(jié)點厌丑。Broker 是 Kafka 的服務節(jié)點定欧,即 Kafka 的服務器。
Topic:Kafka 中的消息以 Topic 為單位進行劃分怒竿,生產(chǎn)者將消息發(fā)送到特定的 Topic砍鸠,而消費者負責訂閱 Topic 的消息并進行消費。
Partition:Topic 是一個邏輯的概念愧口,它可以細分為多個分區(qū)睦番,每個分區(qū)只屬于單個主題。同一個主題下不同分區(qū)包含的消息是不同的,分區(qū)在存儲層面可以看作一個可追加的日志(Log)文件托嚣,消息在被追加到分區(qū)日志文件的時候都會分配一個特定的偏移量(offset)巩检。
Offset:offset 是消息在分區(qū)中的唯一標識,Kafka 通過它來保證消息在分區(qū)內(nèi)的順序性示启,不過 offset 并不跨越分區(qū)兢哭,也就是說,Kafka 保證的是分區(qū)有序性而不是主題有序性夫嗓。
Replication:副本迟螺,是 Kafka 保證數(shù)據(jù)高可用的方式,Kafka 同一 Partition 的數(shù)據(jù)可以在多 Broker 上存在多個副本舍咖,通常只有主副本對外提供讀寫服務矩父,當主副本所在 broker 崩潰或發(fā)生網(wǎng)絡一場,Kafka 會在 Controller 的管理下會重新選擇新的 Leader 副本對外提供讀寫服務排霉。
Record:實際寫入 Kafka 中并可以被讀取的消息記錄窍株。每個 record 包含了 key、value 和 timestamp攻柠。如上圖所示球订。
Kafka中zookeeper的作用
我們在使用Kafka的時候通常都需要配合使用Zookeeper使用,分區(qū)的leader和follower均勻分布在不同的Kafka服務器上面瑰钮,每臺Kafka服務器同時有分區(qū)leader和follower冒滩。
本文書寫時,最新的kafka版本2.8.x版本已經(jīng)脫離了zookeeper浪谴,不過現(xiàn)在用的商用版本都還依賴于zookeeper开睡,這里zookeeper起到了集群管理和元數(shù)據(jù)管理的作用。
如上圖所示苟耻,具體來說zookeeper起到以下幾點作用:
Broker 注冊:Broker 是分布式部署并且之間相互獨立士八,Zookeeper 用來管理注冊到集群的所有 Broker 節(jié)點。
Topic 注冊:在 Kafka 中梁呈,同一個 Topic 的消息會被分成多個分區(qū)并將其分布在多個 Broker 上,這些分區(qū)信息及與 Broker 的對應關(guān)系也都是由 Zookeeper 在維護
生產(chǎn)者負載均衡:由于同一個 Topic 消息會被分區(qū)并將其分布在多個 Broker 上蘸秘,因此官卡,生產(chǎn)者需要將消息合理地發(fā)送到這些分布式的 Broker 上。
消費者負載均衡:與生產(chǎn)者類似醋虏,Kafka 中的消費者同樣需要進行負載均衡來實現(xiàn)多個消費者合理地從對應的 Broker 服務器上接收消息寻咒,每個消費者分組包含若干消費者,每條消息都只會發(fā)送給分組中的一個消費者颈嚼,不同的消費者分組消費自己特定的 Topic 下面的消息毛秘,互不干擾。
Kafka的組成部分
Kafka有四個核心的API:
1.The Producer API
允許一個應用程序發(fā)布一串流式的數(shù)據(jù)到一個或者多個Kafka topic。
Kafka producer 的正常生產(chǎn)邏輯包含以下幾個步驟:
1)配置生產(chǎn)者客戶端參數(shù)常見生產(chǎn)者實例叫挟。
2)構(gòu)建待發(fā)送的消息艰匙。
3)發(fā)送消息。
4)關(guān)閉生產(chǎn)者實例抹恳。
Producer 發(fā)送消息的過程如下圖所示员凝,需要經(jīng)過攔截器,序列化器和分區(qū)器奋献,最終由累加器批量發(fā)送至 Broker健霹。
Kafka Producer 需要以下必要參數(shù):
bootstrap.server:指定 Kafka 的 Broker 的地址
key.serializer:key 序列化器
value.serializer:value 序列化器
2.The Consumer API
允許一個應用程序訂閱一個或多個 topic ,并且對發(fā)布給他們的流式數(shù)據(jù)進行處理瓶蚂。
Kafka 有消費組的概念糖埋,每個消費者只能消費所分配到的分區(qū)的消息,每一個分區(qū)只能被一個消費組中的一個消費者所消費窃这,所以同一個消費組中消費者的數(shù)量如果超過了分區(qū)的數(shù)量瞳别,將會出現(xiàn)有些消費者分配不到消費的分區(qū)。消費組與消費者關(guān)系如下圖所示:
Kafka Consumer Client 消費消息通常包含以下步驟:
1)配置客戶端钦听,創(chuàng)建消費者
2)訂閱主題
3)拉取消息并消費
4)提交消費位移
5)關(guān)閉消費者實例
因為 Kafka 的 Consumer 客戶端是線程不安全的洒试,為了保證線程安全,并提升消費性能朴上,可以在 Consumer 端采用類似 Reactor 的線程模型來消費數(shù)據(jù)垒棋。
Kafka consumer 參數(shù)
bootstrap.servers:連接 broker 地址,host:port 格式痪宰。
group.id:消費者隸屬的消費組叼架。
key.deserializer:與生產(chǎn)者的key.serializer對應,key 的反序列化方式衣撬。
value.deserializer:與生產(chǎn)者的value.serializer對應乖订,value 的反序列化方式。
session.timeout.ms:coordinator 檢測失敗的時間具练。默認 10s 該參數(shù)是 Consumer Group 主動檢測 (組內(nèi)成員 comsummer) 崩潰的時間間隔乍构,類似于心跳過期時間。
auto.offset.reset:該屬性指定了消費者在讀取一個沒有偏移量后者偏移量無效(消費者長時間失效當前的偏移量已經(jīng)過時并且被刪除了)的分區(qū)的情況下扛点,應該作何處理哥遮,默認值是 latest,也就是從最新記錄讀取數(shù)據(jù)(消費者啟動之后生成的記錄)陵究,另一個值是 earliest眠饮,意思是在偏移量無效的情況下,消費者從起始位置開始讀取數(shù)據(jù)铜邮。
enable.auto.commit:否自動提交位移仪召,如果為false寨蹋,則需要在程序中手動提交位移。對于精確到一次的語義扔茅,最好手動提交位移
fetch.max.bytes:單次拉取數(shù)據(jù)的最大字節(jié)數(shù)量
max.poll.records:單次 poll 調(diào)用返回的最大消息數(shù)已旧,如果處理邏輯很輕量,可以適當提高該值咖摹。但是max.poll.records條數(shù)據(jù)需要在在 session.timeout.ms 這個時間內(nèi)處理完 评姨。默認值為 500
request.timeout.ms:一次請求響應的最長等待時間。如果在超時時間內(nèi)未得到響應萤晴,kafka 要么重發(fā)這條消息吐句,要么超過重試次數(shù)的情況下直接置為失敗。
Kafka Rebalance
rebalance 本質(zhì)上是一種協(xié)議店读,規(guī)定了一個 consumer group 下的所有 consumer 如何達成一致來分配訂閱 topic 的每個分區(qū)嗦枢。比如某個 group 下有 20 個 consumer,它訂閱了一個具有 100 個分區(qū)的 topic屯断。正常情況下文虏,Kafka 平均會為每個 consumer 分配 5 個分區(qū)。這個分配的過程就叫 rebalance殖演。
什么時候 rebalance氧秘?
這也是經(jīng)常被提及的一個問題。rebalance 的觸發(fā)條件有三種:
組成員發(fā)生變更(新 consumer 加入組趴久、已有 consumer 主動離開組或已有 consumer 崩潰了——這兩者的區(qū)別后面會談到)
訂閱主題數(shù)發(fā)生變更
訂閱主題的分區(qū)數(shù)發(fā)生變更
如何進行組內(nèi)分區(qū)分配丸相?
Kafka 默認提供了兩種分配策略:Range 和 Round-Robin。當然 Kafka 采用了可插拔式的分配策略彼棍,你可以創(chuàng)建自己的分配器以實現(xiàn)不同的分配策略灭忠。
3.The Streams API
允許一個應用程序作為一個流處理器,消費一個或者多個topic產(chǎn)生的輸入流座硕,然后生產(chǎn)一個輸出流到一個或多個topic中去弛作,在輸入輸出流中進行有效的轉(zhuǎn)換。
4.The Connector API
允許構(gòu)建并運行可重用的生產(chǎn)者或者消費者华匾,將Kafka topics連接到已存在的應用程序或者數(shù)據(jù)系統(tǒng)映琳。比如,連接到一個關(guān)系型數(shù)據(jù)庫蜘拉,捕捉表(table)的所有變更內(nèi)容刊头。