> 文档中心 > 【kafka专栏】服务端副本可靠性原理及配置(含视频)

【kafka专栏】服务端副本可靠性原理及配置(含视频)

kafka要保证消息的生产消费可靠性,需要从三个方面进行管理,一是kafka集群服务端,二是kafka生产者客户端,三是kafka消费者客户端。只有这三个方面都保证可靠性,才能实现消息不重复、不漏掉!本文主要从kafka集群broker客户端的角度说明可靠性及其相关配置,关于其他两个方面请关注本专栏后续文章!(本文对应视频发布地址,参看本专栏目录篇)

文章目录

    • 一、分区副本复制机制
    • 二、不同步分区副本是否可以作为Leader?
    • 三、最小同步副本
      • 3.1. 产生的问题
      • 3.2. 解决问题的办法

一、分区副本复制机制

本专栏之前小节《kafka基础概念解析》我们曾经介绍过,生产者和消费者只和主分区副本进行数据通信,问:从分区副本的数据从哪里来的?答:从分区副本的数据是从主分区副本那里同步过来的。

【kafka专栏】服务端副本可靠性原理及配置(含视频)

这里有几个名词,可能需要大家记一下:

  • AR(Assigned Replicas):代表一个分区的所有副本,包括主(leader)、从(Follower)。
  • ISR(In Sync Replicas):与主分区副本处于同步状态的分区副本,可能有少量的数据延时差异。(通常意义上我们所说的ISR集合中还包含Leader自己
  • OSR(Out Sync Replicas):数据同步状态已经跟不上主分区副本的从分区副本,可能是网络等问题导致。

kafka为了保证高可用(当leader节点挂了之后,kafka依然能提供服务)kafka提供了分区副本复制机制。这个副本是针对分区partition而言的,所以也可以被称为分区副本(partition replica),可以通过 default.replication.factor对replica的数目进行配置,默认值为1,表示不对topic的分区进行备份。如果配置为2,表示除了leader节点,对于topic里的每一个partition,都会有一个额外的副本。

分区实例:
举一个例子:

  • 有3个broker、hostname名称为broker-a、broker-b、broker-c
  • 在kafka集群有一个主题叫做topic1
  • topic1有3个partition分区(红、黄、蓝)
  • default.replication.factor被设置为2(每个分区有两个副本)。分区副本中有一个被选举为Leader。

如下图所示:

【kafka专栏】服务端副本可靠性原理及配置(含视频)

假如分区副本的Leader挂掉了,kafka会从剩余的分区副本中再选出一个作为Leader,继续提供服务。这种分区副本复制机制保证了:其中一台或几台服务器挂掉,kafka集群依然有分区副本可用。当然,如果存在某个副本的Broker服务都挂掉了,该分区就彻底地挂掉了。

二、不同步分区副本是否可以作为Leader?

从上文我们知道,与主分区副本处于同步状态的分区副本被称为ISR(包含Leader自己),数据同步状态已经跟不上主分区副本的从分区副本被称为OSR。

正常情况下,如果Leader挂掉,kafka肯定从ISR中选举一个Leader。但是假如ISR列表为空,就只能从OSR中选举Leader。下面的这个参数的作用就是配置:是否允许从OSR中选举Leader。

unclean.leader.election.enable=false

默认值是true,我们给它设置为false。因为当允许从OSR中选举Leader,并且Leader负责和客户端的数据通信,OSR内的分区副本数据数据是严重滞后的,不同步的,所以会导致数据丢失。

配置这个参数代表我们接受一种情况:宁可接受kafka服务挂掉,不提供服务;也不能接受苟延残喘的提供服务,最终导致数据丢失

三、最小同步副本

kafka生产者在进行数据发送的时候,可以设置一个参数叫做acks。如果acks=all,代表消息需要在所有的ISR分区副本都被持久化数据保存成功之后,Broker服务端才可以告诉生产者,这个消息已经发送成功了。

3.1. 产生的问题

假设一种特殊情况:如果[1,2,3]一共3个分区副本,1是Leader分区副本,其他是Follower分区副本。由于网络的问题,可能[2,3]分区副本的数据同步进度远远落后于1分区副本,那么现在ISR集合中就只剩下1号分区副本自己。那么问题出现了,当生产者acks=all的时候,这种情况下只有1号Leader分区副本持久化成功,这个消息就算发送成功了,因为ISR集合中只有1。这个时候如果Leader分区副本也挂了怎么办,是不是数据就丢失了?

  • 第一:数据确实发出来了,而且回复生产者数据发送成功了
  • 第二:Leader自己挂了,而Follower没有同步的数据

3.2. 解决问题的办法

这种情况下明智的做法是:当ISR中只剩下Leader的时候,broker就不应该接收生产者发送的消息。宁可接受kafka服务挂掉,不提供服务;也不能接受苟延残喘的提供服务,最终导致数据丢失

通常需要设置的一个参数是min.insync.replicas=n。当生产者设置acks为“all”(或“-1”)时,该配置min.insync.replicas指定了必须确认的写操作的最小副本数量(即数据同步的最小副本数量)。代表的语义是:如果生产者acks=all,在发送消息时,Broker的ISR数量没有达到n,Broker不能接收这条消息,需要直接给生产者报错。触发一个异常(NotEnoughReplicas或NotEnoughReplicasAfterAppend)。

如果一个包含 3 个分区副本的主题,所以如果使用配置min.insync.replicas>=2,那么当只剩下一个Leader分区副本时,Leader分区副本就变成只读了(只能提供消费,不能接收生产数据)。这样可以有效的避免在kafka主题分区更换选举过程中,数据的写入和读取出现非预期的行为。