Kafka 的 高水位(High Watermark, HW) 和 低水位(Low Watermark, LW) 是和數據存儲、消費進度、日志清理等密切相關的重要概念。我們用一個 “蓄水池” 的比喻來形象地解釋它們的作用。
1. Kafka 里的數據像一個蓄水池
Kafka 的數據存儲在 日志(log segment) 里,每個分區(partition)就像一個不斷增長的日志文件,數據會隨著生產者(producer)的發送不斷增加,消費者(consumer)從中讀取數據。你可以把它想象成一個 不斷注水的蓄水池。
2. 高水位(HW):消費安全線
高水位(HW) 就像是蓄水池里的 “最低可見水位”,只有水面之下的水(數據)才是消費者能喝(消費)到的。
- Kafka 是分布式的,每個分區的消息可能被多個副本(replica)存儲在不同的機器上。
- 只有當 所有 ISR(In-Sync Replicas,即同步副本)都確認收到了某個消息,這個消息才被認為是“穩定的”并可以被消費者消費。
- 高水位(HW)指的就是最早的 ISR 共同確認的那條消息的偏移量(offset),消費者只能消費到這個位置的數據,再往后的數據還不能保證穩定,不能消費。
類比:
- 你可以想象蓄水池里有一根透明的管子,管子以下的水可以喝(已經被多個副本確認)。
- 但管子上面的水(新寫入但未完全確認的消息)還在“沉淀”過程中,可能會被回滾(刪除)。
作用:
- 保證數據一致性,確保所有消費者只能消費已經被多個副本確認的數據,避免數據丟失。
3. 低水位(LW):清理水池底部的陳舊數據
低水位(LW) 就是 “蓄水池的排水口”,用來刪除過舊的數據,防止池子被塞滿。
Kafka 會根據 日志清理策略(Log Retention Policy) 來刪除舊數據,比如:
- 按時間刪除(log.retention.hours):只保留最近 X 小時的數據。
- 按大小刪除(log.retention.bytes):當日志文件超過一定大小后,刪除最早的數據。
低水位(LW)指的就是最早還能被 Kafka 保留的偏移量(offset),更早的數據都會被清理掉,防止日志無限增長。
類比:
- 如果池子太滿,底部的水就要排走,以騰出空間給新的水(數據)。
- 低水位(LW)以下的數據(offset)會被 Kafka 自動清理,消費者也無法再讀取這些數據。
作用:
- 避免日志文件無限增長,節省存儲空間。
- 提高 Kafka 性能,防止查詢過大數據時變慢。
4. 高水位和低水位的關系
- 高水位(HW)不斷上升,確保數據可以安全消費。
- 低水位(LW)也在上升,確保老數據及時清理。
- 高水位 - 低水位之間的數據就是 Kafka 當前可消費的數據,消費者只能消費這個范圍的數據。
5. 總結
概念 | 作用 | 類比 |
---|---|---|
高水位(HW) | 保障消費者只能消費到安全的數據 | 透明管子以下的水,可安全飲用 |
低水位(LW) | 觸發日志清理,避免存儲爆炸 | 水池排水口,定期排掉老水 |
6. 延伸思考
- 如果 ISR 副本少了(比如機器故障),高水位就不會提升,導致消費者無法消費新數據。
- 如果低水位設得太低,可能會讓消費者還沒消費就被刪數據,導致數據丟失。
- Kafka 通過合理調整
log.retention.*
和副本同步策略,來平衡存儲和消費的可靠性。
這樣理解的話,Kafka 高低水位的原理是不是就清晰很多了?