Kafka分区和副本都是由副本管理器所管理的,引入副本就是为了提高可用性,整个集群中如何判断代理是否存活?

  • 一个存活的代理必须与Zookeeper保持连接,通过Zookeeper的心跳机制来实现的

  • 作为一个Follower副本,该副本不能落后Leader副本太久(怎么算太久?)replica.lag.max.messages配置项确定的,默认为10秒。

满足上面2个条件则认为该副本或者节点处于同步中(in sync)。Leader副本会追中所有同步中的节点,一旦一个节点宕机或者落后太久,Leader就会将该节点从同步副本中ISR列表中移除。Follower从Leader副本同步数据不是同步也不是单纯的异步。Kafka采用了一个同步列表的方式来做了同步和异步的折中。


分区:

将一个主题分成一个或多个分区,物理上对应一个目录。每个主题的分区编号都是唯一的,从0开始。分区目录下存储的是该分区的日志段,包括日志数据文件和两个索引文件。分区数可以大于节点数,但是副本数不能大于节点数量。创建主题是分区数量最好为代理数量的整数倍


LEO:每个分区最后一条消息的位置,每个副本都有自己的LEO

HW:ISR列表中最小的LEO作为一个分区的HW。HW之前表示已经提交的消息,消费者只能消费已经提交的,HW之后的消息消费者不能消费,因为HW之后的消息表示还没有被ISR列表中的Follower同步。

Kafka(五)Kafka分区与副本_第1张图片

也就是说消息写入到所有副本的日志中才算提交,才可以被消费者消费。这是对消费者来说的,生产者是否要等待消息都被写入所有副本之后才收到返回是另外一回事,这个可以通过acks来配置,kafka为生产者提供3种消息确认机制(request.required.acks参数):

  • acks=0,生产者无需等待代理返回确认,就是可以连续发送,但是无法保证消息是否被代理收到。

  • acks=1,生产者需要等待Leader副本以及成功写入日志。这种方式降级了消息丢失的可能性,但是也只是Leader写入日志而不管Follower是否写入。

  • acks=-1,Leader副本和所有Follower都写入日志才会向生产者发送确认信息。


副本:

一个分区可有一个或多个副本,Leaeder副本用于接收读写请求,Follower副本用于做备份,一个分区只能有一个Leader和0个或多个Follower,Leader副本处理分区的所有读写请求并维护自身以及Follower副本的状态。当Leader副本失效时,会从Follower副本中选举一个新的Leader副本对外提供读写服务。