Bootstrap

kafka分区副本机制

            Kafka为分区引入了多副本(Replica)机制,通过增加副本数量可以提升容灾能力。同一分区的不同副本中保存的是相同消息(在同一时刻,副本之前并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步。副本处于不同的broker中,当leader副本出现故障时,从follower副本中重新选举新的leader副本对外提供服务。Kafka通过多副本机制实现了故障的自动转义,当Kafka集群中某个broker失效时扔然能够保证服务可用。

        如下图,Kfaka集群中有4个broker,某个主题中有3个分区,且副本因子(即副本个数)也为3,如此每个分区便有1个leader副本和2个follower副本。生产者和消费者只与leader副本进行交互,而follower副本只负责消息的同步,很多时候follower副本中的消息相对leader副本而言会有一定的滞后。

      Kafka消费端也具备一定的容灾能力。Consumer使用拉(Pull)模式从服务端拉去消息,并且保存消费的具体位置,当消费者宕机后恢复上线时可以根据之前保存的消费位置重新拉取需要的消息进行消费,这样就不会造成消息丢失。

       分区中 的所有副本统称为 AR ( Assigned Replicas ) 。 所有与 leader 副本保持一定程度同步的副本(包括 leader 副本在内〕组成 ISR On-Sync Replicas ) , ISR 集合是 AR 集合中 的一个子集 。 消息会先发送到 leadr 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步,同步期间内 follower 副本相对于 leader 副本而言会有一定程度的滞后 。 前面所说的“一定程度的同步”是指可忍受的滞后范围,这个范围可以通过参数进行配置 。 与 leader 副本同步滞后过多的副本(不包括 leader 副本)组成 OSR ( Out-of-Sync Replicas ),由此可见, AR=ISR+OSR 。在正常情况下, 所有的 follower 副本都应该与 leader 副本保持一定程度 的同步,即 AR=ISR,OSR 集合为空。
          leader 副本负责维护和跟踪 ISR 集合中所有 follower 副 本 的滞后状态, 当 follower 副本落后太多或失效时, leader 副本会把它从 ISR 集合中剔除 。 如果 OSR 集合中有 follower 副本 “追上’’了 leader 副本,那么 leader 副本会把它从 OSR 集合转移至 ISR 集合 。 默认情况下, 当 leader 副本发生故障时,只 有在 ISR 集合中的副本才有资格被选举为新的 leader, 而在 OSR 集合中的副本则没有任何机会(不过这个原则也可以通过修改相应的参数配置来改变) 。
         ISR 与 HW 和 LEO 也有紧密的关系 。 HW 是 High Watermark 的缩写,俗称高水位,它标识了一个特定 的消息偏移量( offset),消费者只能拉取到这个offset之前的消息 。如图所示,它代表一个日志文件,这个日志文件中有 9 条消息,第一条消息的 offset( LogStartOffset )为 0,最后一条消息的 offset 为 8, offset 为 9 的消息用虚线框表示,代表下一条待写入的消息。日志文件的 HW 为 6,表示消费者只能拉取到 offset 在 0 至 5 之间的消息,而offset为 6 的消息对消费者而言是不可见的 。

        LEO是Log End Offset 的缩写,它标识当前日志文件中下一条待写入消息 的 offset,图中offset 为 9 的位置即为当前日志文件的LEO, LEO的大小相当于当前日志分区中最后一条消息的offset 值加 1。分区ISR 集合中的每个副本都会维护自身的LEO ,而 ISR集合中最小的 LEO即为分区的LEO ,对消费者而言只能消费HW之前的消息。
         为了让读者更好地理解 ISR 集合, 以及 HW 和 LEO 之间的关系, 下面通过一个简单的示例来进行相关的说明 。 如图 1-5 所示,假设某个分区的 ISR 集合中有 3 个副本,即一个 leader副本和 2 个 follower 副本,此时分区的 LEO 和 HW 都为 3 。 消息 3 和消息 4 从生产者发出之后会被先存入 leader 副本,如图 1 -6 所示

          在消息写入 leader 副本之后, follower 副本会发送拉取请求来拉取消息 3 和消息 4 以进行消息同步。在同步过程中,不同的 follow副本的同步效率也不尽相同。如图 1-7 所示, 在某一时刻follower1完全跟上了 leader 副本而 follower2 只同步了消息 3 ,如此 leader 副本的 LEO 为 5,follower1 的 LEO 为 5 , follower2 的 LEO 为 4 , 那么当前分区的 HW 取最小值 4 ,此时消费者可以消 费到 offset 为 0 至 3 之间的消息。

    写入消息(情形的如图 1-8 所示,所有的副本都成功写入了消息 3 和消息 4,整个分区的HW 和 LEO 都变为 5,因此消费者可以消费到 offset 为 4 的消息了 。

           由此可见, Kafka 的复制机制既不是完全的同步复制,也不是单纯的异步复制。事实上,同步复制要求所有能工作的 follower 副本都复制完,这条消息才会被确认为已成功提交,这种复制方式极大地影响了性能。而在异步复制方式下, follower 副本异步地从 leader 副本中 复制数据,数据只要被 leader 副本写入就被认为已经成功提交。在这种情况下,如果 follower 副本都还没有复制完而落后于 leader 副本,突然 leader 副本着机,则会造成数据丢失。 Kafka 使用的这种 ISR 的方式则有效地权衡了数据可靠性和性能之间的关系。
 

;