生産環境中使用Kafka,參數調優非常重要,而Kafka參數衆多,我們的java的Configuration代碼中,經常設定的參數如下:
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("retries", 10);
props.put("retry.backoff.ms", 500);
props.put("acks", "1");
KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);
- buffer.memory
Kafka的用戶端發送資料到伺服器,不是來一條就發一條,而是經過緩沖的,也就是說,通過KafkaProducer發送出去的消息都是先進入到用戶端本地的記憶體緩沖裡,然後把很多消息收內建一個一個的Batch,再發送到Broker上去的,這樣性能才可能高。
buffer.memory的本質就是用來限制KafkaProducer能夠使用的記憶體緩沖的大小的,預設值32MB。
如果buffer.memory設定的太小,可能導緻的問題是:消息快速的寫入記憶體緩沖裡,但Sender線程來不及把Request發送到Kafka伺服器,會造成記憶體緩沖很快就被寫滿。而一旦被寫滿,就會阻塞使用者線程,不讓繼續往Kafka寫消息了。
是以“buffer.memory”參數需要結合實際業務情況壓測,需要測算在生産環境中使用者線程會以每秒多少消息的頻率來寫入記憶體緩沖。經過壓測,調試出來一個合理值。
- batch.size
每個Batch要存放batch.size大小的資料後,才可以發送出去。比如說batch.size預設值是16KB,那麼裡面湊夠16KB的資料才會發送。
理論上來說,提升batch.size的大小,可以允許更多的資料緩沖在裡面,那麼一次Request發送出去的資料量就更多了,這樣吞吐量可能會有所提升。
但是batch.size也不能過大,要是資料老是緩沖在Batch裡遲遲不發送出去,那麼發送消息的延遲就會很高。
一般可以嘗試把這個參數調節大些,利用生産環境發消息負載測試一下。
- linger.ms
一個Batch被建立之後,最多過多久,不管這個Batch有沒有寫滿,都必須發送出去了。
比如說batch.size是16KB,但是現在某個低峰時間段,發送消息量很小。這會導緻可能Batch被建立之後,有消息進來,但是遲遲無法湊夠16KB,難道此時就一直等着嗎?
當然不是,假設設定“linger.ms”是50ms,那麼隻要這個Batch從建立開始到現在已經過了50ms了,哪怕他還沒滿16KB,也會被發送出去。
是以“linger.ms”決定了消息一旦寫入一個Batch,最多等待這麼多時間,他一定會跟着Batch一起發送出去。
linger.ms配合batch.size一起來設定,可避免一個Batch遲遲湊不滿,導緻消息一直積壓在記憶體裡發送不出去的情況。
- max.request.size
決定了每次發送給Kafka伺服器請求消息的最大大小。
如果發送的消息都是大封包消息,每條消息都是資料較大,例如一條消息可能要20KB。此時batch.size需要調大些,比如設定512KB,buffer.memory也需要調大些,比如設定128MB。
隻有這樣,才能在大消息的場景下,還能使用Batch打包多條消息的機制。
此時“max.request.size”也得同步增加。
- retries和retries.backoff.ms
重試機制,也就是如果一個請求失敗了可以重試幾次,每次重試的間隔是多少毫秒,根據業務場景需要設定。
- acks
含義 | |
Producer 往叢集發送資料不需要等到叢集的傳回,不確定消息發送成功。安全性最低但是效率最高。 | |
1 | Producer 往叢集發送資料隻要 Leader 應答就可以發送下一條,隻確定 Leader 接收成功。 |
-1 或 all | Producer 往叢集發送資料需要所有的ISR Follower 都完成從 Leader 的同步才會發送下一條,確定 Leader 發送成功和所有的副本都成功接收。安全性最高,但是效率最低。 |