Kafka參數調優實戰

一、背景引入:不少同窗看不懂kafka參數

今天給你們聊一個頗有意思的話題,你們知道不少公司都會基於Kafka做爲MQ來開發一些複雜的大型系統。面試

而在使用Kafka的客戶端編寫代碼與服務器交互的時候,是須要對客戶端設置不少的參數的。apache

因此我就見過不少年輕的同窗,可能剛剛加入團隊,對Kafka這個技術其實並非很瞭解。bootstrap

此時就會致使他們看團隊裏的一些資深同事寫的一些代碼,會看不懂是怎麼回事,不瞭解背後的含義,這裏面尤爲是一些Kafka參數的設置服務器

因此這篇文章,咱們仍是採用老規矩畫圖的形式,來聊聊Kafka生產端一些常見參數的設置,讓你們下次看到一些Kafka客戶端設置的參數時,不會再感到發怵。測試


二、一段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);

三、內存緩衝的大小

首先咱們看看「buffer.memory」這個參數是什麼意思?spa

Kafka的客戶端發送數據到服務器,通常都是要通過緩衝的,也就是說,你經過KafkaProducer發送出去的消息都是先進入到客戶端本地的內存緩衝裏,而後把不少消息收集成一個一個的Batch,再發送到Broker上去的。線程

 

Kafka參數調優實戰,看這篇文章就夠了!

 

 

因此這個「buffer.memory」的本質就是用來約束KafkaProducer可以使用的內存緩衝的大小的,他的默認值是32MB。3d

那麼既然瞭解了這個含義,你們想一下,在生產項目裏,這個參數應該怎麼來設置呢?調試

你能夠先想一下,若是這個內存緩衝設置的太小的話,可能會致使一個什麼問題?server

首先要明確一點,那就是在內存緩衝裏大量的消息會緩衝在裏面,造成一個一個的Batch,每一個Batch裏包含多條消息。

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

 

Kafka參數調優實戰,看這篇文章就夠了!

 

那麼若是要是內存設置的過小,可能致使一個問題:消息快速的寫入內存緩衝裏面,可是Sender線程來不及把Request發送到Kafka服務器。

這樣是否是會形成內存緩衝很快就被寫滿?一旦被寫滿,就會阻塞用戶線程,不讓繼續往Kafka寫消息了。

因此對於「buffer.memory」這個參數應該結合本身的實際狀況來進行壓測,你須要測算一下在生產環境,你的用戶線程會以每秒多少消息的頻率來寫入內存緩衝。

好比說每秒300條消息,那麼你就須要壓測一下,假設內存緩衝就32MB,每秒寫300條消息到內存緩衝,是否會常常把內存緩衝寫滿?通過這樣的壓測,你能夠調試出來一個合理的內存大小。


四、多少數據打包爲一個Batch合適?

接着你須要思考第二個問題,就是你的「batch.size」應該如何設置?這個東西是決定了你的每一個Batch要存放多少數據就能夠發送出去了。

好比說你要是給一個Batch設置成是16KB的大小,那麼裏面湊夠16KB的數據就能夠發送了。

這個參數的默認值是16KB,通常能夠嘗試把這個參數調節大一些,而後利用本身的生產環境發消息的負載來測試一下。

好比說發送消息的頻率就是每秒300條,那麼若是好比「batch.size」調節到了32KB,或者64KB,是否能夠提高發送消息的總體吞吐量。

由於理論上來講,提高batch的大小,能夠容許更多的數據緩衝在裏面,那麼一次Request發送出去的數據量就更多了,這樣吞吐量可能會有所提高。

可是這個東西也不能無限的大,過於大了以後,要是數據總是緩衝在Batch裏遲遲不發送出去,那麼豈不是你發送消息的延遲就會很高。

好比說,一條消息進入了Batch,可是要等待5秒鐘Batch才湊滿了64KB,才能發送出去。那這條消息的延遲就是5秒鐘。

因此須要在這裏按照生產環境的發消息的速率,調節不一樣的Batch大小本身測試一下最終出去的吞吐量以及消息的 延遲,設置一個最合理的參數。


五、要是一個Batch遲遲沒法湊滿怎麼辦?

要是一個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形同虛設,一直湊不滿數據。


六、最大請求大小

「max.request.size」這個參數決定了每次發送給Kafka服務器請求的最大大小,同時也會限制你一條消息的最大大小也不能超過這個參數設置的值,這個其實能夠根據你本身的消息的大小來靈活的調整。

給你們舉個例子,大家公司發送的消息都是那種大的報文消息,每條消息都是不少的數據,一條消息可能都要20KB。

此時你的batch.size是否是就須要調節大一些?好比設置個512KB?而後你的buffer.memory是否是要給的大一些?好比設置個128MB?

只有這樣,才能讓你在大消息的場景下,還能使用Batch打包多條消息的機制。可是此時「max.request.size」是否是也得同步增長?

由於可能你的一個請求是很大的,默認他是1MB,你是否是能夠適當調大一些,好比調節到5MB?


七、重試機制

「retries」和「retries.backoff.ms」決定了重試機制,也就是若是一個請求失敗了能夠重試幾回,每次重試的間隔是多少毫秒。

這個你們適當設置幾回重試的機會,給必定的重試間隔便可,好比給100ms的重試間隔。


八、持久化機制

「acks」參數決定了發送出去的消息要採用什麼樣的持久化策略,這個涉及到了不少其餘的概念,你們能夠參考以前專門爲「acks」寫過的一篇文章:

簡歷寫Kafka,面試官大機率會讓你講acks參數對消息持久化的影響

相關文章
相關標籤/搜索