kafka springboot 集成配置+測試

 kafka在代碼中的的使用主要是對配置文件的配置,與服務器上配置文件的配置,

實際 生產、消費 的代碼很簡單。

----------------------------------------------------------------------------------------------------------------------------------

partitions,replication(設置)

auto.create.topics.enable參數爲true(默認值就是true) ,在配置文件中沒有找到

num.partitions(默認值爲1)個分區和default.replication.factor(默認值爲1)個副本

default.replication.factor,在配置文件中也沒有找到,

副本的數量不能大於broker的數量(集羣服務器的數量)

如果是一個副本,則會均勻分佈在broker中

不建議將auto.create.topics.enable參數設置爲true,因爲這個參數會影響topic的管理與維護。

消息會通過負載均衡發佈到不同的分區上,消費者會監測偏移量來獲取哪個分區有新數據,從而從該分區上拉取消息數據。

分區數越多,在一定程度上會提升消息處理的吞吐量,因爲kafka是基於文件進行讀寫,因此也需要打開更多的文件句柄,也會增加一定的性能開銷。

如果分區過多,那麼日誌分段也會很多,寫的時候由於是批量寫,其實就會變成隨機寫了,隨機 I/O 這個時候對性能影響很大。所以一般來說 Kafka 不能有太多的 Partition。

當broker和partions一樣時,就均勻分佈在不同的broker上。

建議:

replication.factor 主題副本數量 (主題指的是topic)<= broker數量(集羣服務器個數)

partitions數量 >= broker數量(建議相等就可以了,如果想大於的話建議使用broker的整數倍,這樣對集羣壓力比較均勻)

 

----------------------------------------------------------------------------------------------------------------------------------

生產者機制:

 

設置緩衝區大小

buffer.memory

Sender線程會把多個Batch打包成一個Request發送到Kafka服務器上去。

緩衝區太小:會導致消息快速的寫入內存緩衝裏面,但是Sender線程來不及把Request發送到Kafka服務器。

數據打包的大小

batch.size

提升batch的大小,可以允許更多的數據緩衝在裏面,那麼一次Request發送出去的數據量就更多了,這樣吞吐量可能會有所提升。過於大了之後,要是數據老是緩衝在Batch裏遲遲不發送出去,那麼豈不是你發送消息的延遲就會很高。

Batch的最大存活時間

linger.ms

設置爲25ms,則在batch從創建開始到25ms的時候,即使沒有達到batch設置的大小,以一樣會發送出去。避免一個Batch遲遲湊不滿,導致消息一直積壓在內存裏發送不出去的情況。這是一個很關鍵的參數。

最大請求設置

max.request.size

每次發送給Kafka服務器請求的最大大小,即一個 request 請求的最大大小

重試機制

“retries”和“retries.backoff.ms”決定了重試機制,也就是如果一個請求失敗了可以重試幾次,每次重試的間隔是多少毫秒。比如給100ms的重試間隔。

 

----------------------------------------------------------------------------------------------------------------------------------

Broker(集羣中一個服務器,稱爲一個 broker)

Broker發生宕機的情況下,該broker中存儲的partion(leader)會停止工作,該partion會在剩餘的broker中選出新的leader(serially的方式),kafka controller節點broker自動完成,

在通常情況下,當一個broker有計劃地停止服務時,那麼controller會在服務停止之前,將該broker上的所有leader一個個地移走。由於單個leader的移動時間大約只需要花費幾毫秒,因此從客戶層面看,有計劃的服務停機只會導致系統在很小時間窗口中不可用。(注:在有計劃地停機時,系統每一個時間窗口只會轉移一個leader,其他leader皆處於可用狀態。)

根據經驗,如果你十分關心消息延遲問題,限制每個broker節點的partition數量是一個很好的主意:對於b個broker節點和複製因子爲r的kafka集羣,整個kafka集羣的partition數量最好不超過100*b*r個,即單個partition的leader數量不超過100.

根據經驗,爲了達到較好的吞吐量,我們必須在producer端爲每個分區分配至少幾十KB的內存(指的是producer.batch-size,但是在這個值增加之後,producer.buffer-memory,緩衝區的大小也要相應的發生變化),並且在分區數量顯著增加時調整可以使用的內存數量。

----------------------------------------------------------------------------------------------------------------------------------

數據在kafka裏的存儲機制:

Message

Topic

Partition

Segment = index.index(索引) + data.log(數據)

一臺服務器爲一個Broker(假設3臺服務器,就有3個broker)

一個broker有多個partition(假設,一個broker存在3個partition)

一個topic可以存儲在多個patition上面,任何一個Partition,只有Leader是對外提供讀寫服務的

Partition多副本,稱爲,一個partition有多個副本。(並不是說每一個broker上面存儲的partion個數都相等,)假設一個Topic拆分爲了3個Partition,分別是Partition0,Partiton1,Partition2,此時每個Partition就有2個副本。

Partition(Leader)對外提供讀寫服務。

Leader接收到數據,Follower副本會不停的給他發送請求嘗試去拉取最新的數據,拉取到自己本地後,寫入磁盤中。

kafka broker 主從節點同步的方式,ISR全稱是“In-Sync Replicas”,也就是保持同步的副本,他的含義就是,跟Leader始終保持同步的Follower有哪些。

 

----------------------------------------------------------------------------------------------------------------------------------

消費:

在kafka0.10.1之後的版本中,將session.timeout.ms 和 max.poll.interval.ms 解耦了。也就是說:new KafkaConsumer對象後,在while true循環中執行consumer.poll拉取消息這個過程中,其實背後是有2個線程的,即一個kafka consumer實例包含2個線程:一個是heartbeat 線程,另一個是processing線程,processing線程可理解爲調用consumer.poll方法執行消息處理邏輯的線程,而heartbeat線程是一個後臺線程,對程序員是"隱藏不見"的。如果消息處理邏輯很複雜,比如說需要處理5min,那麼 max.poll.interval.ms可設置成比5min大一點的值。而heartbeat 線程則和上面提到的參數 heartbeat.interval.ms有關,heartbeat線程 每隔heartbeat.interval.ms向coordinator發送一個心跳包,證明自己還活着。只要 heartbeat線程 在 session.timeout.ms 時間內 向 coordinator發送過心跳包,那麼 group coordinator就認爲當前的kafka consumer是活着的。 

consumer在max.poll.interval.ms的時間內定時向 group coordinator發送心跳,則認爲在 max.poll.interval.ms的時間內該consumer是有效的,

心跳heartbeat-interval,默認是3秒,即session.timeout的1/3

如果在session.timeout時間內沒有檢測到心跳,則認爲該consumer失效

spring.kafka.consumer.max-poll-records=500   (拉取的最大爲500條數據)
spring.session.timeout=10000ms(在10s內,消費者沒有發送心跳則認爲該消費者死掉)
spring.kafka.consumer.heartbeat-interval=3000ms
max.poll.interval.ms(默認是5分鐘,五分鐘後沒有再次進行poll則,該消費者死掉)

如果設置爲手動提交,但是在代碼中沒有,設置爲手動提交,

代碼會正常的進行 生產、消費,

如果服務再次重啓,則,會將之前沒有提交的offset 數據再次消費一遍

在網上查找的資料(說的是,springboot 集成 kafka,在設置爲手動提交之後,如果沒有在代碼中手動提交則springboot框架會自動幫你提交)

親自測試,springboot 不會自動的幫你提交 offset 偏移量。

 

-----------------------------------------------------------------------------------------------------------------------------

我的項目中的springboot + kakfa配置內容

要修改的內容:(基於手動提交的方式進行設置,手動提交的方式比較安全,可控性比較高)

#以逗號分隔的主機:端口對列表,用於建立與Kafka羣集的初始連接。不需要指定所有的的 broker
spring.kafka.bootstrap-servers=192.168.232.100:9092
#在偵聽器容器中運行的線程數,多線程消費(這個也要合理的進行設置,不要設置的太多)
spring.kafka.listener.concurrency=3
#========================================================== kafka ===============================================================
#以逗號分隔的主機:端口對列表,用於建立與Kafka羣集的初始連接。不需要指定所有的的 broker
spring.kafka.bootstrap-servers=192.168.232.100:9092

##################################  producer的配置參數(開始)##################################
#procedure要求leader在考慮完成請求之前收到的確認數,用於控制發送記錄在服務端的持久化,其值可以爲如下:
#acks = 0 如果設置爲零,則生產者將不會等待來自服務器的任何確認,該記錄將立即添加到套接字緩衝區並視爲已發送。在這種情況下,無法保證服務器已收到記錄,並且重試配置將不會生效(因爲客戶端通常不會知道任何故障),爲每條記錄返回的偏移量始終設置爲-1。
#acks = 1 這意味着leader會將記錄寫入其本地日誌,但無需等待所有副本服務器的完全確認即可做出迴應,在這種情況下,如果leader在確認記錄後所在的broker立即宕機,但在將數據複製到所有的副本服務器之前,則記錄將會丟失。
#acks = all 這意味着leader將等待完整的同步副本集以確認記錄,這保證了只要至少一個同步副本服務器仍然存活,記錄就不會丟失,這是最強有力的保證,這相當於acks = -1的設置。
#可以設置的值爲:all, -1, 0, 1
spring.kafka.producer.acks=all
#如果該值大於零時,表示啓用重試失敗的發送次數,瞬時失敗的原因可能包括:元數據信息失效、副本數量不足、超時、位移越界或未知分區等
#消息的重試不會造成消息的重複發送。
spring.kafka.producer.retries=3
#retry.backoff.ms 重試的時間間隔
#spring.

#生產者可用於緩衝等待發送到服務器的記錄的內存總字節數,默認值爲33554432,32MB
spring.kafka.producer.buffer-memory=33554432
#每當多個記錄被髮送到同一分區時,生產者將嘗試將記錄一起批量處理爲更少的請求,batch 越小,producer的吞吐量越低
#這有助於提升客戶端和服務器上的性能,此配置控制默認批量大小(以字節爲單位),默認值爲16384 即 16kb
spring.kafka.producer.batch-size=16384
#linger.ms設置(吞吐量和延時性能),默認是0,表示不做停留
#spring.

#max.in.flight.requests.per.connection設置(吞吐量和延時性能)
#spring.

#生產者生成的所有數據的壓縮類型,此配置接受標準壓縮編解碼器('gzip','snappy','lz4'),
#它還接受'uncompressed'以及'producer',分別表示 沒有壓縮 以及 保留生產者設置的原始壓縮編解碼器,
#默認值爲producer,推薦使用 lz4
spring.kafka.producer.compression-type=lz4
#ID在發出請求時傳遞給服務器,用於服務器端日誌記錄
spring.kafka.producer.client-id=
#key的Serializer類,實現類實現了接口org.apache.kafka.common.serialization.Serializer
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
#值的Serializer類,實現類實現了接口org.apache.kafka.common.serialization.Serializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer


################################## consumer的配置參數(開始)##################################
#是否自動提交偏移量,默認是true,爲避免出現重複數據和數據丟失,設置爲false,然後手動提交偏移量
spring.kafka.consumer.enable-auto-commit=false
#如果'enable.auto.commit'爲true,則消費者偏移自動提交給Kafka的頻率(以毫秒爲單位),默認值爲5000。
spring.kafka.consumer.auto-commit-interval=5000ms
#心跳與消費者協調員之間的預期時間(毫秒),默認3000,這個值必須設置的小於session.timeout.ms,通常設置的值要低於session.timeout.ms的1/3。
spring.kafka.consumer.heartbeat-interval=3000ms
#當Kafka中沒有初始偏移量或者服務器上不再存在當前偏移量時該怎麼辦,默認值爲latest,表示自動將偏移重置爲最新的偏移量
#可選的值爲latest, earliest, none
spring.kafka.consumer.auto-offset-reset=latest
#檢測消費者失敗的超時,10000,這個值必須設置在broker configuration中的group.min.session.timeout.ms 與 group.max.session.timeout.ms之間。
#spring.session.timeout=10000ms

#在一次調用poll()中返回的最大記錄數。500
spring.kafka.consumer.max-poll-records=500
#max.poll.interval.ms,在使用消費者組管理時,調用poll()之間的最大延遲。這提出了消費者在獲取更多記錄之前可以閒置的時間量的上界。如果在此超時到期之前未調用poll(),則認爲使用者失敗,並且組將重新平衡以將分區重新分配給其他成員。
#默認300000,5分鐘

#ID在發出請求時傳遞給服務器;用於服務器端日誌記錄。
#spring.kafka.consumer.client-id;

#如果沒有足夠的數據立即滿足“fetch.min.bytes”給出的要求,服務器在回答獲取請求之前將阻塞的最長時間(以毫秒爲單位)
#默認值爲500
#spring.kafka.consumer.fetch-max-wait;

#服務器應以字節爲單位返回獲取請求的最小數據量,默認值爲1,對應的kafka的參數爲fetch.min.bytes。
#spring.kafka.consumer.fetch-min-size;

#用於標識此使用者所屬的使用者組的唯一字符串。
#spring.kafka.consumer.group-id;

#密鑰的反序列化器類,實現類實現了接口org.apache.kafka.common.serialization.Deserializer
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
#值的反序列化器類,實現類實現了接口org.apache.kafka.common.serialization.Deserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer


################################## listener的配置參數(結束)##################################
#偵聽器的AckMode,參見https://docs.spring.io/spring-kafka/reference/htmlsingle/#committing-offsets
#當enable.auto.commit的值設置爲false時,該值會生效;爲true時不會生效,listener負責ack,背後也是批量上去,手動提交offset需要的配置
#RECORD :當listener一讀到消息,就提交offset
#BATCH : poll() 函數讀取到的所有消息,就提交offset
#TIME : 當超過設置的ackTime ,即提交Offset
#COUNT :當超過設置的COUNT,即提交Offset
#COUNT_TIME :TIME和COUNT兩個條件都滿足,提交offset
#MANUAL : Acknowledgment.acknowledge()即提交Offset,和Batch類似
#MANUAL_IMMEDIATE: Acknowledgment.acknowledge()被調用即提交Offset
spring.kafka.listener.ack-mode=MANUAL
#在偵聽器容器中運行的線程數,多線程消費
spring.kafka.listener.concurrency=3
#輪訓消費者時的超時時間,ms
spring.kafka.listener.poll-timeout=10000ms
#監控間隔時間
spring.kafka.listener.monitor-interval=10000ms
#當ackMode爲“COUNT”或“COUNT_TIME”時,偏移提交之間的記錄數
spring.kafka.listener.ack-count;
#當ackMode爲“TIME”或“COUNT_TIME”時,偏移提交之間的時間(以毫秒爲單位)
spring.kafka.listener.ack-time;

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章