1. 程式人生 > 其它 >kafka中的acks引數

kafka中的acks引數

首先這個acks引數,是在KafkaProducer,也就是生產者客戶端裡設定的也就是說,你往kafka寫資料的時候,就可以來設定這個acks引數。

這個引數實際上有三種常見的值可以設定,分別是:0、1 和 all。

第一種選擇是把acks引數設定為0

我的KafkaProducer在客戶端,只要把訊息傳送出去,不管那條資料有沒有在哪怕Partition Leader上落到磁碟,我就不管他了,直接就認為這個訊息傳送成功了。
如果你採用這種設定的話,那麼你必須注意的一點是,可能你傳送出去的訊息還在半路。結果呢,Partition Leader所在Broker就直接掛了,然後結果你的客戶端還認為訊息傳送成功了,此時就會導致這條訊息就丟失了。

第二種選擇是設定 acks = 1

只要Partition Leader接收到訊息而且寫入本地磁碟了,就認為成功了,不管他其他的Follower有沒有同步過去這條訊息了。
這種設定其實是kafka預設的設定,大家請注意,劃重點!這是預設的設定
也就是說,預設情況下,你要是不管acks這個引數,只要Partition Leader寫成功就算成功。
但是這裡有一個問題,萬一Partition Leader剛剛接收到訊息,Follower還沒來得及同步過去,結果Leader所在的broker宕機了,此時也會導致這條訊息丟失,因為人家客戶端已經認為傳送成功了。

最後一種情況,就是設定acks=all

Partition Leader接收到訊息之後,還必須要求ISR列表裡跟Leader保持同步的那些Follower都要把訊息同步過去,才能認為這條訊息是寫入成功了。
如果說Partition Leader剛接收到了訊息,但是結果Follower沒有收到訊息,此時Leader宕機了,那麼客戶端會感知到這個訊息沒傳送成功,他會重試再次傳送訊息過去。
此時可能Partition 2的Follower變成Leader了,此時ISR列表裡只有最新的這個Follower轉變成的Leader了,那麼只要這個新的Leader接收訊息就算成功了。

acks=all 就可以代表資料一定不會丟失了嗎?
當然不是,如果你的Partition只有一個副本,也就是一個Leader,任何Follower都沒有,你認為acks=all有用嗎?
當然沒用了,因為ISR裡就一個Leader,他接收完訊息後宕機,也會導致資料丟失。
所以說,這個acks=all,必須跟ISR列表裡至少有2個以上的副本配合使用,起碼是有一個Leader和一個Follower才可以。
這樣才能保證說寫一條資料過去,一定是2個以上的副本都收到了才算是成功,此時任何一個副本宕機,不會導致資料丟失。