kafka可靠性保证

时间:2022-12-20 21:54:37

1、概念

  1. 创建Topic的时候可以指定--replication-factor 3 ,表示分区的副本数,不要超过broker的数量。
  2. Leader是负责读写的节点,而其他副本则是Follower。Producer只把消息发送到Leader,Follower定期地到Leader上Pull数据。
  3. ISR是Leader负责维护的与其保持同步的Replica列表,即当前活跃的副本列表。如果一个Follow落后太多,Leader会将它从ISR中移除。落后太多意思是该Follow复制的消息Follow长时间没有向Leader发送fetch请求(参数: replica.lag.time.max.ms 默认值:10000)。
  4. 为了保证可靠性,可以设置acks=all 。Follower收到消息后,会像Leader发送ACK。一旦Leader收到了ISR中所有Replica的ACK,Leader就commit,那么Leader就向Producer发送ACK。

2、副本的分配:

        当某个topic的--replication-factor 为N(N>1)时,每个Partition都有N个副本,称作replica。原则上是将replica均匀的分配到整个集群上。不仅如此,partition的分配也同样需要均匀分配,为了更好的负载均衡。

副本分配的三个目标:

  • 均衡地将副本分散于各个broker上
  • 对于某个broker上分配的分区,它的其他副本在其他broker上
  • 如果所有的broker都有机架信息,尽量将分区的各个副本分配到不同机架上的broker。

在不考虑机架信息的情况下:

  • 第一个副本分区通过轮询的方式挑选一个broker,进行分配。该轮询从broker列表的随机位置进行轮询。
  • 其余副本通过增加偏移进行分配。

kafka可靠性保证

 

3、失效副本

失效副本的判定

replica.lag.time.max.ms 默认大小为10000。

  • 当ISR中的一个Follower副本滞后Leader副本的时间超过参数replica.lag.time.max.ms 指定的值时即判定为副本失效,需要将此Follower副本剔出除ISR。
  • 具体实现原理:当Follower副本将Leader副本的LEO之前的日志全部同步时,则认为该Follower副本已经追赶上Leader副本,此时更新该副本的lastCaughtUpTimeMs标识。
  • Kafka的副本管理器(ReplicaManager)启动时会启动一个副本过期检测的定时任务,而这个定时任务会定时检查当前时间与副本的lastCaughtUpTimeMs差值是否大于参数replica.lag.time.max.ms 指定的值。

Kafka源码注释中说明了一般有两种情况会导致副本失效:

  1. Follower副本进程卡住,在一段时间内没有向Leader副本发起同步请求,比如频繁的Full GC。
  2. Follower副本进程同步过慢,在一段时间内都无法追赶上Leader副本,比如IO开销过大。
  • 如果通过工具增加了副本因子,那么新增加的副本在赶上Leader副本之前也都是处于失效状态的。
  • 如果一个Follower副本由于某些原因(比如宕机)而下线,之后又上线,在追赶上Leader副本之前也是出于失效状态。
  • 失效副本的分区个数是用于衡量Kafka性能指标的重要部分。Kafka本身提供了一个相关的指标,即UnderReplicatedPartitions,这个可以通过JMX访问:

    kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions

  • 取值范围是大于等于0的整数。注意:如果Kafka集群正在做分区迁移(kafka-reassignpartitions.sh)的时候,这个值也会大于0。

4、副本复制

        日志复制算法(log replication algorithm)必须提供的基本保证是,如果它告诉客户端消息已被提交,而当前Leader出现故障,新选出的Leader也必须具有该消息。在出现故障时,Kafka会从挂掉Leader的ISR里面选择一个Follower作为这个分区新的Leader。

        每个分区的 leader 会维护一个in-sync replica(同步副本列表,又称 ISR)。当Producer向broker发送消息,消息先写入到对应Leader分区,然后复制到这个分区的所有副本中。ACKS=ALL时,只有将消息成功复制到所有同步副本(ISR)后,这条消息才算被提交。

什么情况下会导致一个副本与 leader 失去同步

一个副本与 leader 失去同步的原因有很多,主要包括:

  • 慢副本(Slow replica):follower replica 在一段时间内一直无法赶上 leader 的写进度。造成这种情况的最常见原因之一是 follower replica 上的 I/O瓶颈,导致它持久化日志的时间比它从 leader 消费消息的时间要长;
  • 卡住副本(Stuck replica):follower replica 在很长一段时间内停止从 leader 获取消息。这可能是以为 GC 停顿,或者副本出现故障;
  • 刚启动副本(Bootstrapping replica):当用户给某个主题增加副本因子时,新的 follower replicas 是不同步的,直到它跟上 leader 的日志。

        当副本落后于 leader 分区时,这个副本被认为是不同步或滞后的。在 Kafka中,副本的滞后于Leader是根据replica.lag.time.max.ms 来衡量。

如何确认某个副本处于滞后状态

        通过 replica.lag.time.max.ms 来检测卡住副本(Stuck replica)在所有情况下都能很好地工作。它跟踪 follower 副本没有向 leader 发送获取请求的时间,通过这个可以推断 follower 是否正常。另一方面,使用消息数量检测不同步慢副本(Slow replica)的模型只有在为单个主题或具有同类流量模式的多个主题设置这些参数时才能很好地工作,但我们发现它不能扩展到生产集群中所有主题。