Kafka性能調優分析-線上環境篇


 正文前先來一波福利推薦:

福利一:

百萬年薪架構師視頻,該視頻可以學到很多東西,是本人花錢買的VIP課程,學習消化了一年,為了支持一下女朋友公眾號也方便大家學習,共享給大家。

福利二:

畢業答辯以及工作上各種答辯,平時積累了不少精品PPT,現在共享給大家,大大小小加起來有幾千套,總有適合你的一款,很多是網上是下載不到。

獲取方式:

微信關注 精品3分鍾 ,id為 jingpin3mins,關注后回復   百萬年薪架構師 ,精品收藏PPT  獲取雲盤鏈接,謝謝大家支持!

------------------------正文開始---------------------------

 

一、背景介紹:

  在平時的開發中,使用kafka來發送數據已經非常熟悉,但是在使用的過程中,其實並沒有比較深入的探索kafka使用過程中

一些參數配置,帶來的損失可能就是沒有充分的發揮出kfka的優勢,無法很好的滿足業務場景。在意識這個問題后,專門騰出

時間來總結一下kakfa參數配置的調優,以充分發揮kafka在低時延,高吞吐等不同場景下的優勢。

二、通用介紹:

-------- 生產者配置 -------

  常規參數設置解析:

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092"); 
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("buffer.memory", 67108864); 
props.put("batch.size", 131072); 
props.put("linger.ms", 100); 
props.put("max.request.size", 10485760); 
props.put("acks", "1"); 
props.put("retries", 10); 
props.put("retry.backoff.ms", 500);

KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);

  

1、內存緩沖的大小:buffer.memory

 

  首先我們看看“buffer.memory”這個參數是什么意思?

  Kafka的客戶端發送數據到服務器,一般都是要經過緩沖的,也就是說,你通過KafkaProducer發送出去的消息都是先進入到客戶端本地的內存緩沖

里,然后把很多消息收集成一個一個的Batch,再發送到Broker上去的。所以這個“buffer.memory”的本質就是用來約束KafkaProducer能夠使用的內存緩

沖的大小的,他的默認值是32MB。那么既然了解了這個含義,大家想一下,在生產項目里,這個參數應該怎么來設置呢?你可以先想一下,如果這個內

存緩沖設置的過小的話,可能會導致一個什么問題?首先要明確一點,那就是在內存緩沖里大量的消息會緩沖在里面,形成一個一個的Batch,每個Batch

里包含多條消息。然后KafkaProducer有一個Sender線程會把多個Batch打包成一個Request發送到Kafka服務器上去。

 

那么如果要是內存設置的太小:

  可能導致一個問題:消息快速的寫入內存緩沖里面,但是Sender線程來不及把Request發送到Kafka服務器。這樣是不是會造成內存緩沖很快就被寫滿?一旦被寫滿,

就會阻塞用戶線程,不讓繼續往Kafka寫消息了。所以對於“buffer.memory”這個參數應該結合自己的實際情況來進行壓測,你需要測算一下在生產環境,你的用戶線程會

以每秒多少消息的頻率來寫入內存緩沖。比如說每秒300條消息,那么你就需要壓測一下,假設內存緩沖就32MB,每秒寫300條消息到內存緩沖,是否會經常把內存緩沖

寫滿?經過這樣的壓測,你可以調試出來一個合理的內存大小。

 

 2、多少數據打包為一個Batch合適:batch.size

  接着你需要思考第二個問題,就是你的“batch.size”應該如何設置?

  這個東西是決定了你的每個Batch要存放多少數據就可以發送出去了。比如說你要是給一個Batch設置成是16KB的大小,那么里面湊夠16KB的數據就可以發送了。這個參數的

默認值是16KB,一般可以嘗試把這個參數調節大一些,然后利用自己的生產環境發消息的負載來測試一下。

比如說發送消息的頻率就是每秒300條,那么如果比如“batch.size”調節到了32KB,或者64KB,是否可以提升發送消息的整體吞吐量。因為理論上來說,提升batch的大小,可以允許

更多的數據緩沖在里面,那么一次Request發送出去的數據量就更多了,這樣吞吐量可能會有所提升。但是這個東西也不能無限的大,過於大了之后,要是數據老是緩沖在Batch里遲

遲不發送出去,那么豈不是你發送消息的延遲就會很高。比如說,一條消息進入了Batch,但是要等待5秒鍾Batch才湊滿了64KB,才能發送出去。那這條消息的延遲就是5秒鍾。所以

需要在這里按照生產環境的發消息的速率,調節不同的Batch大小自己測試一下最終出去的吞吐量以及消息的 延遲,設置一個最合理的參數。

 

3、要是一個Batch遲遲無法湊滿怎么辦:linger.ms

  要是一個Batch遲遲無法湊滿,此時就需要引入另外一個參數了,“linger.ms”,他的含義就是說一個Batch被創建之后,最多過多久,不管這個Batch有沒有寫滿,都必須發送出去了。

給大家舉個例子,比如說batch.size是16kb,但是現在某個低峰時間段,發送消息很慢。這就導致可能Batch被創建之后,陸陸續續有消息進來,但是遲遲無法湊夠16KB,難道此時就一直等着嗎?

當然不是,假設你現在設置“linger.ms”是50ms,那么只要這個Batch從創建開始到現在已經過了50ms了,哪怕他還沒滿16KB,也要發送他出去了。所以“linger.ms”決定了你的消息一旦寫入一個Batch,

最多等待這么多時間,他一定會跟着Batch一起發送出去。避免一個Batch遲遲湊不滿,導致消息一直積壓在內存里發送不出去的情況。這是一個很關鍵的參數。這個參數一般要非常慎重的來設置,

要配合batch.size一起來設置。舉個例子,首先假設你的Batch是32KB,那么你得估算一下,正常情況下,一般多久會湊夠一個Batch,比如正常來說可能20ms就會湊夠一個Batch。

那么你的linger.ms就可以設置為25ms,也就是說,正常來說,大部分的Batch在20ms內都會湊滿,但是你的linger.ms可以保證,哪怕遇到低峰時期,20ms湊不滿一個Batch,還是會在25ms之后強制Batch發送出去。

如果要是你把linger.ms設置的太小了,比如說默認就是0ms,或者你設置個5ms,那可能導致你的Batch雖然設置了32KB,但是經常是還沒湊夠32KB的數據,5ms之后就直接強制Batch發送出去,這樣也不太好其實,會導致你的Batch形同虛設,一直湊不滿數據

 

4、最大請求大小 :“max.request.size”

  這個參數決定了每次發送給Kafka服務器請求的最大大小,同時也會限制你一條消息的最大大小也不能超過這個參數設置的值,這個其實可以根據你自己的消息的大小來靈活的調整。給大家舉個例子,你們公司發送的消息都是那種大的報文消息,每條消息都是很多的數據,一條消息可能都要20KB。此時你的batch.size是不是就需要調節大一些?比如設置個512KB?然后你的buffer.memory是不是要給的大一些?比如設置個128MB?只有這樣,才能讓你在大消息的場景下,還能使用Batch打包多條消息的機制。但是此時“max.request.size”是不是也得同步增加?

因為可能你的一個請求是很大的,默認他是1MB,你是不是可以適當調大一些,比如調節到5MB?

 

5、重試機制:“retries”和“retries.backoff.ms”

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

這個大家適當設置幾次重試的機會,給一定的重試間隔即可,比如給100ms的重試間隔。

 

6、確認機制:acks

此配置是表明當一次produce請求被認為完成時的確認值。特別是,多少個其他brokers必須已經提交了數據到他們的log並且向他們的leader確認了這些信息。典型的值包括:
 0: 表示producer從來不等待來自broker的確認信息(和0.7一樣的行為)。這個選擇提供了最小的時延但同時風險最大(因為當server宕機時,數據將會丟失)。
 1:表示獲得leader replica已經接收了數據的確認信息。這個選擇時延較小同時確保了server確認接收成功。
-1:producer會獲得所有同步replicas都收到數據的確認。同時時延最大,然而,這種方式並沒有完全消除丟失消息的風險,因為同步replicas的數量可能是1。如果你想確保某些replicas接收到數據,那么你應該在topic-level設置中選項min.insync.replicas設置一下。

 

 7、min.insync.replicas:

  當生產者設置應答為"all"(或“-1”)時,此配置指定了成功寫入的副本應答的最小數。如果沒滿足此最小數,則生產者將引發異常(NotEnoughReplicas或NotEnoughReplicasAfterAppend)
當min.insync.replicas和acks強制更大的耐用性時。典型的情況是創建一個副本為3的topic,將min.insync.replicas設置為2,並設置acks為“all”。如果多數副本沒有收到寫入,這將確保生產者引發異常。

-------- 消費者配置 -------

 1、fetch.min.bytes:

  每次fetch請求時,server應該返回的最小字節數。如果沒有足夠的數據返回,請求會等待,直到足夠的數據才會返回。

2、auto.commit.enable

  如果為真,consumer所fetch的消息的offset將會自動的同步到zookeeper。這項提交的offset將在進程掛掉時,由新的consumer使用。

 

三、優化進階篇:

------------------------------------- 優化之 --- 提升吞吐量 -----------------------------------

 

 ------------------------------------- 優化之 --- 保證低時延 -----------------------------------

 

 ------------------------------------- 優化之 --- 保證高持久 -----------------------------------
 

 

---------------------------------------------------- 參數說明 ----------------------------------------------------

replica復制配置

     每個follow從leader拉取消息進行同步數據,follow同步性能由這幾個參數決定:

  • num.replica.fetchers:拉取線程數
  • replica.fetch.min.bytes:拉取最小字節數
  • replica.fetch.min.bytes:拉取最大字節數
  • replica.fetch.wait.max.ms:最大等待時間

     優化建議

  • num.replica.fetchers 配置多可以提高follower的I/O並發度,單位時間內leader持有更多請求,相應負載會增大,需要根據機器硬件資源做權衡
  • replica.fetch.min.bytes=1 默認配置為1字節,否則讀取消息不及時
  • replica.fetch.max.bytes= 5 * 1024 * 1024 默認為1MB,這個值太小,5MB為宜,根據業務情況調整
  • replica.fetch.wait.max.ms follow拉取頻率,頻率過高,會導致cpu飆升,因為leader無數據同步,leader會積壓大量無效請求情況

壓縮速度

  • compression.type:壓縮的速度上lz4=snappy<gzip。

有序性

  • max.in.flight.requests.per.connection (affects ordering,設置為1可以保證有序性,但是發送性能會受影響。不為1的時候,如果發生消息重發則會亂序),在單個連接中,producer客戶端在阻塞之前,可以允許未被確認的最大請求數,即當一個連接中未被確認的請求數超過了該設置,那么該producer客戶端將會阻塞。注意:如果該值設置得比1大,當出現發送失敗的情況,且retries配置項又開啟時,那么存在消息被重新排序的風險。

 

冪等性:enable.idempotence

  重要性:低
  類型:Boolean
  默認值:false

  是否使用冪等性。如果設置為true,表示producer將確保每一條消息都恰好有一份備份;如果設置為false,則表示producer因發送數據到broker失敗重試使,可能往數據流中寫入多分重試的消息。

  注意:如果使用idempotence,即enable.idempotence為true,那么要求配置項max.in.flight.requests.per.connection的值必須小於或等於5;配置項retries的值必須大於0;acks配置項必須設置為all。如果這些值沒有被用戶明確地設置,那么系統將自動選擇合適的值。如果設置  的值不合適,那么會拋出ConfigException異常。

網絡和IO線程配置優化

 配置參數

  • num.network.threads:Broker處理消息的最大線程數
  • num.io.threads:Broker處理磁盤IO的線程數

 優化建議

  • 一般num.network.threads主要處理網絡io,讀寫緩沖區數據,基本沒有io等待,配置線程數量為cpu核數加1
  • num.io.threads主要進行磁盤io操作,高峰期可能有些io等待,因此配置需要大些。配置線程數量為cpu核數2倍,最大不超過3倍.

日志保留策略配置

  當kafka server的被寫入海量消息后,會生成很多數據文件,且占用大量磁盤空間,如果不及時清理,可能磁盤空間不夠用,kafka默認是保留7天。

 優化建議

  • 減少日志保留時間,建議三天或則更多時間。log.retention.hours=72
  • 段文件配置1GB,有利於快速回收磁盤空間,重啟kafka加載也會加快(如果文件過小,則文件數量比較多,kafka啟動時是單線程掃描目錄(log.dir)下所有數據文件),文件較多時性能會稍微降低。log.segment.bytes=1073741824

log數據文件刷盤策略

為了大幅度提高producer寫入吞吐量,需要定期批量寫文件

  優化建議

  • 每當producer寫入10000條消息時,刷數據到磁盤。log.flush.interval.messages=10000
  • 每間隔1秒鍾時間,刷數據到磁盤。log.flush.interval.ms=1000


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM