什么是水位
kafka中用水位來描述,
一個分區(qū)中的可見數(shù)據(jù)的offset。
大概你需要知道這幾點:
-
hw(水位)你可以理解成是一個全局(所有副本最小offset)的offset,
針對的是一個分區(qū) - LEO代表著該副本的所有消息的最大offset,
針對的是一個副本,也就是每個副本都有LEO,并且不一樣。
其中所有副本中最小的LEO就是水位

為什么要水位?
為了保障數(shù)據(jù)的一致性
Kafka中水位的運作
當(dāng) Leader收到一條消息并寫入成功,
其LEO則和馬上 +1.
副本會定期去和Leader進(jìn)行同步,
每同步一個消息,其自己的LEO相應(yīng)+1,
而水位則是所有副本最小的LEO,
所以也會慢慢進(jìn)行增加。
和ACK的關(guān)系
其實沒有必然的關(guān)系,
ACK是用來保證數(shù)據(jù)不丟失的,
而 hw 是用來保證客戶端消費的一致性的,
不過當(dāng)ACK=-1,
因為會等到數(shù)據(jù)完全寫入到所有副本,
才能返回成功,
也就是說所有副本的LEO都 +1,
其水位必然也會 +1,
這個時候就可以避免數(shù)據(jù)丟失了。
否則則會存在數(shù)據(jù)丟失的風(fēng)險-
為什么ACK != -1 數(shù)據(jù)就可能丟失
比如一個分區(qū),四個副本1,2,3,4:
1:LEO = 10(Leader)
2:LEO = 8
3:LEO = 7
4:LEO = 6
此時 hw = 6,
當(dāng)1 號Leader掛掉了,
3號當(dāng)選了新Leader,
則所有存活副本首先會將hw之外的所有數(shù)據(jù)清除,
然后從Leader同步水位之后的數(shù)據(jù)
比如2號副本:
先清除本身數(shù)據(jù)7,8,LEO變成6,
然后去Leader同步6之后的數(shù)據(jù),
哪怕老Leader1號恢復(fù)了,6-10號數(shù)據(jù)還在,
也需要將宕機時候的hw之后的數(shù)據(jù)全部清除,
重新從Leader同步數(shù)據(jù)所以...結(jié)論就是,
只要水位沒有覆蓋的數(shù)據(jù),
都存在丟失的風(fēng)險。
這也是hw的意義所在,
保證數(shù)據(jù)的一致性