在 Kafka 中,高水位 (High Watermark)和低水位(Low Watermark)是与消息的消费进度和数据一致性相关的重要概念。它们与 Kafka 的分区、副本同步和数据的可靠性保障密切相关,确保 Kafka 系统中的消息不会丢失,并且消费者可以按顺序消费消息。
以下是对高水位和低水位的详细解释:
高水位(High Watermark,简称 HWM)
- 高水位是一个分区中所有副本(包括 Leader 和 Follower)都已经同步并且确认的消息偏移量。
- 高水位表示该偏移量之前的消息对所有副本来说都是 已确认 的,也就是说,所有的副本都已经同步了这部分数据。
- 对消费者来说,高水位是它们能够 消费 的最新消息的偏移量。
- 高水位确保了数据的 一致性,只有当高水位更新时,消费者才能消费到新的消息。
低水位(Low Watermark,简称 LWM)
- 低水位 指的是分区中所有副本同步进度的 最小偏移量。也就是说,低水位是所有副本的同步进度中最落后的那个副本的偏移量。
- 低水位用来描述 副本同步的延迟,它表示最慢副本可以保证读取到的最新消息的偏移量。
- 低水位主要用于反映系统的 数据同步状态,可以帮助 Kafka 判断哪些副本落后,需要进行数据同步。
✅ 高水位的作用
- 消费者消费的依据 :
- 高水位标记了 消费者可以读取的最大偏移量 ,消费者只能消费 高水位之前 的消息。
- 消费者在消费时,不会消费高水位之后的消息,确保消费数据的一致性和完整性。
- 高水位也决定了 消费的进度,当消费者消费到某个偏移量时,Kafka 会更新这个消费者所在分区的高水位。
- 副本同步的保障 :
- 高水位也作为所有副本的同步进度的标记,表示到高水位的消息,所有副本都已经同步并且保证数据一致性。
- 只有当 Leader 的消息已经成功同步到所有 ISR(In-Sync Replicas)中的副本时,才会更新高水位。
- 数据的持久性 :
- Kafka 中的高水位表示所有 ISR 中的副本都已经成功复制的数据位置。只有高水位以下的数据被认为是"已提交"的消息,才是可靠的。如果某个副本失效,只要高水位以下的数据已经被其他副本同步,这些数据就不会丢失,因此高水位是 Kafka 保证数据持久性的关键机制。
- 这也确保了 Kafka 对消息的持久性承诺:即使某个副本失败,只要其他副本中有数据,它就不会丢失。
✅ 低水位的作用
- 副本的同步进度 :
- 低水位反映了分区中副本同步进度的 最小值,如果某个副本落后于其他副本,它的同步进度就会影响到低水位的更新。
- 当某个副本的日志跟不上其他副本的更新时,低水位就会保持在这个副本的最后同步偏移量。低水位有助于监控 副本的同步延迟。
- 确保一致性 :
- Kafka 使用低水位来确保数据的一致性。如果一个副本落后于 Leader 太多,它会被从 ISR(In-Sync Replicas)中移除,这意味着该副本不再与 Leader 保持同步,不再能保证数据的一致性。
- 低水位帮助 Kafka 确保只有 同步的副本 才能成为 Leader,当一个副本被移出 ISR 时,Kafka 会选择其他副本作为 Leader,以避免数据丢失和不一致。
- 判断副本的健康状态 :
- Kafka 会根据低水位来判断 副本的健康状态。如果一个副本与 Leader 的同步进度落后太多,它会被认为是 "落后副本",并且不会参与消息的写入或读取。
✅ 高水位和低水位在 Kafka 中的工作流程
- 写入消息 :
- 生产者将消息写入到 Kafka 分区的 Leader 上。Leader 会将这些消息异步地同步到所有的副本。
- 同步副本的进度 :
- 当 Follower 从 Leader 中拉取消息时,它会将这些消息同步到自己的日志中。
- 一旦 Follower 完成了对某条消息的同步,它会向 Leader 发送确认。
- 更新高水位 :
- 高水位是基于所有副本(包括 Leader 和 Follower)的同步进度来更新的,只有所有副本都同步了某个偏移量后,Leader 才会更新高水位。
- 更新低水位 :
- 低水位会随着副本的同步进度而变化,它会追踪最慢副本的同步偏移量。副本同步落后时,低水位就会相应地落后,反映出分区的副本同步情况。
- 消费者消费 :
- 消费者只能消费 高水位之前 的消息。如果消息已经被 Leader 和所有同步副本确认,则消息会被认为是已提交,可以被消费者消费。
- 副本故障和数据恢复 :
- 如果某个副本掉队或者失败,Kafka 会自动将它从 ISR 中移除,并且会从其他副本中选择新的副本来恢复数据。
- 当 Kafka 发现某个副本落后,低水位会向这个副本靠拢,帮助管理副本的同步进度。
✅ 配置项和调优
min.insync.replicas
:- 这个配置项控制分区的最小同步副本数。只有当分区的 ISR 中的副本数大于或等于
min.insync.replicas
时,生产者才能写入数据。如果副本数量不足,Kafka 会拒绝生产者的写入请求,避免数据丢失。
- 这个配置项控制分区的最小同步副本数。只有当分区的 ISR 中的副本数大于或等于
acks
:- 生产者的
acks
配置决定了生产者写入时需要等待的确认级别。acks=all
表示生产者等待所有副本(Leader 和所有 ISR 中的副本)的确认,确保写入消息的可靠性。
- 生产者的
unclean.leader.election.enable
:- 这个配置项控制是否允许选举一个不完全同步的副本作为 Leader。如果该选项为
true
,在没有足够的同步副本时,Kafka 可能会选举一个副本作为 Leader,可能导致数据丢失。因此,通常建议设置为false
。
- 这个配置项控制是否允许选举一个不完全同步的副本作为 Leader。如果该选项为
🧠 总结
在 Kafka 中,高水位 和低水位是确保消息一致性、容错性和高可用性的重要机制。
- 高水位(HWM):标记所有副本都已经确认并同步的消息偏移量,消费者只能消费到高水位之前的消息。
- 低水位(LWM):表示副本同步进度的最小值,反映出最慢副本的同步状态,帮助管理副本的健康性。
这些机制确保了 Kafka 在分布式环境中能够保证数据的一致性、可靠性和高可用性,并且能够容忍副本的故障和网络延迟等问题。