Kafka如果保证数据的可靠性

2022年10月25日12:14:12

数据的可靠性保证

Kafka如果保证数据的可靠性

为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果 producer 收到 ack,就会进行下一轮的发送,否则重新发送数据。

副本数据同步策略

方案 优点 缺点
半数以上完成同步,就发送 ack 延迟低 选举新的 leader 时,容忍 n 台节点的故障,需要 2n+1 个副 本
全部完成同步,才发送 ack 选举新的 leader 时,容忍 n 台节点的故障,需要 n+1 个副 本 延迟高

Kafka 选择了第二种方案,原因如下:

  1. 同样为了容忍 n 台节点的故障,第一种方案需要 2n+1 个副本,而第二种方案只需要 n+1 个副本,而Kafka 的每个分区都有大量的数据,第一种方案会造成大量数据的冗余。
  2. 虽然第二种方案的网络延迟会比较高,但网络延迟对 Kafka 的影响较小。

AR、ISR、OSR

采用第二种方案之后,设想以下情景:leader 收到数据,所有 follower 都开始同步数据, 但有一个 follower,因为某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去, 直到它完成同步,才能发送 ack。这个问题怎么解决呢?
Kafka如果保证数据的可靠性
Kafka中,把 follower 可以按照不同状态分为三类 —— AR、ISR、OSR。

  • 分区的所有副本称为 「AR」(Assigned Replicas —— 已分配的副本)
  • 所有与leader副本保持一定程度同步的副本(包括 leader 副本在内)组成 「ISR」(In-Sync Replicas——在同步中的副本)
  • 由于 follower 副本同步滞后过多的副本(不包括 leader 副本)组成 「OSR」(Out-of-Sync Replias)
  • AR = ISR + OSR
  • 正常情况下,所有的 follower 副本都应该与 leader 副本保持同步,即 AR = ISR,OSR 集合为空。

Leader 维护了一个动态的in-sync replica set (ISR),意为和 leader 保持同步的 follower 集合。当 ISR 中的 follower 完成数据的同步之后,leader 就会给 follower 发送 ack。如果 follower 长时间 未 向 leader 同 步 数 据 , 则 该 follower 将 被 踢 出 ISR , 该 时 间 阈 值 由replica.lag.time.max.ms 参数设定。Leader 发生故障之后,就会从 ISR 中选举新的 leader。

ACK应答机制

对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失, 所以没必要等 ISR 中的 follower 全部接收成功。
所以 Kafka 为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡, 选择以下的配置:

  • 0:producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟,broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据
    Kafka如果保证数据的可靠性

  • 1:producer 等待broker 的 ack,partition 的 leader 落盘成功后返回 ack
    Kafka如果保证数据的可靠性

    如果在 follower 同步成功之前leader 故障,那么将会丢失数据
    Kafka如果保证数据的可靠性

  • -1(all):producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盘成功后才返回 ack
    Kafka如果保证数据的可靠性

    但是如果在 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复
    Kafka如果保证数据的可靠性

分区的leader和follower

在 Kafka 中,每个 topic 都可以配置多个分区以及多个副本。每个分区都有一个 leader 以及 0 个或者多个follower,在创建 topic 时,Kafka 会将每个分区的 leader 均匀地分配在每个 broker 上。我们正常使用 kafka 是感觉不到 leader、follower 的存在的。但其实,所有的读写操作都是由 leader 处理,而所有的 follower 都复制 leader 的日志数据文件,如果 leader 出现故障时,follower 就会被选举为 leader。所以,可以这样说:
Kafka如果保证数据的可靠性

  • Kafka 中的 leader 负责处理读写操作,而 follower 只负责副本数据的同步
  • 如果 leader 出现故障,其他 follower 会被重新选举为 leader
  • follower 像一个 consumer 一样,拉取 leader 对应分区的数据,并保存到日志数据文件中

故障处理

Kafka如果保证数据的可靠性
LEO:指的是每个副本最大的 offset;
HW:指的是消费者能见到的最大的 offset,ISR 队列中最小的 LEO

  • follower 故障
    • follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后,follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
  • leader 故障
    • leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。
      注:这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。

Controller介绍

  • Kafka 启动时,会在所有的 broker 中选择一个 controller
  • 前面 leader 和 follower 是针对 partition,而 controller 是针对 broker 的
  • 创建 topic、或者添加分区、修改副本数量之类的管理任务都是由 controller 完成的
  • Kafka 分区 leader 的选举,也是由 controller 决定的

Controller的选举

  • 在 Kafka 集群启动的时候,每个 broker 都会尝试去 ZooKeeper 上注册成为 Controller(ZK临时节点)
  • 但只有一个竞争成功,其他的 broker 会注册该节点的监视器
  • 一但该临时节点状态发生变化,就可以进行相应的处理
  • Controller 也是高可用的,一旦某个 broker 崩溃,其他的 broker 会重新注册为 Controller

Controller选举partition leader

  • 所有 Partition 的 leader 选举都由 controller 决定
  • controller 会将 leader 的改变直接通过 RPC 的方式通知需为此作出响应的 Broker
  • controller 读取到当前分区的 ISR,只要有一个 Replica 还幸存,就选择其中一个作为 leader,否则,则任意选择一个 Replica 作为 leader
  • 如果该 partition 的所有 Replica 都已经宕机,则新的 leader 为 -1

为什么不能通过ZK的方式来选举partition的leader?

  • Kafka 集群如果业务很多的情况下,会有很多的 partition
  • 假设某个 broker 宕机,就会出现很多的 partiton 都需要重新选举 leader
  • 如果使用 zookeeper 选举 leader,会给 zookeeper 带来巨大的压力。所以,kafka 中 leader 的选举不能使用 ZK 来实现
  • 作者:一位木带感情的码农
  • 原文链接:https://blog.csdn.net/weixin_44758876/article/details/120345503
    更新时间:2022年10月25日12:14:12 ,共 3036 字。