Kafka-Concept

  关于Kafka的文章主要是为了学习在分布式系统下非常重要的部分如数据复制数据分区的真正实践同时对于消息队列的使用并不是很多从而通过学习Kafka相关内容来进行深入当然没有大型项目关于Kafka的深入实践很难结合业务场景来调优最佳实践和更加深刻的认知但还是希望通过这种方式来进行入门了解万变不离其宗的分布式系统下的复杂性

  Kafka本身算是一个复杂项目从而不想一下子掉进开源代码中本次学习还是按照想要了解数据复制数据分区负载均衡这种主题来进行学习故而有些点比如log本地写入磁盘网络模型等内容暂时不是我的重点

  本节是关于Kafka比较重要的组成部分进行简单的介绍方便接下来更深入的了解

  • 消息

  消息是Kafka中最基本的数据单元消息可以看成是数据库里的一个数据行或一条记录由字节数组组成

  • Topic

  topic是用于存储消息的逻辑概念可以看作一个消息集合每个生产者可以有多个生产者向其中推送消息然后由任意多个消费者进行消费

  每个Topic可以划分成若干个分区(Partition)一个分区就是一个提交日志消息以追加的方式写入分区然后以先入先出的顺序读取由于一个主题一般包含几个分区因此无法在整个主题范围内保证消息的顺序但可以保证消息在单个分区的顺序

  • broker和集群

  一个独立的Kafka服务器被称为brokerbroker接受来自生产者的消息为消息设置偏移量并提交消息到磁盘保存broker为消费者提供服务对读取分区的请求作出响应返回已经提交到磁盘上的消息

  broker是集群的组成部分每个集群都有一个broker同时充当了集群控制器的角色自动从集群的活跃成员中选举出来控制器负责管理工作包括将分区分配给broker和监控broker在集群中一个分区从属于一个broker该broker被称为分区的首领一个分区可以分配给多个broker这个时候会发生分区复制这种复制机制为分区提供了消息冗余如果有一个broker失效其他broker可以接管领导权然后相关的消费者和生产者都要重新连接到新的首领

  • ISR集合

  ISR(In-Sync Replica)集合表示的是目前可用(alive)且消息量与Leader相差不多的副本集合这是整个副本集合的一个子集其进入条件为
1. 副本所在节点必须是连接畅通的
2. 副本最后一条消息的offset与Leader副本的最后一条消息的offset相等或者上一次的catchUp的时间与当
前时间的差值小于一个设定的阈值

  leaderEndOffset == logEndOffset || currentTimeMs - lastCaughtUpTimeMs <= replicaMaxLagMs

  每个分区中的Leader副本都会维护此分区的ISR集合写请求首先由Leader副本处理之后Follower副本会从Leader上拉取写入的消息ISR集合是Kafka数据可靠性的一部分保证类似于ZK中的少数服从多数当Leader副本不可用时ISR集合中的其他副本由于和Leader的offset保持一致从而可以充当新Leader副本供读和写

  • HW & LEO

  LEOLog End Offset是所有的副本都会有的一个offset它指的是当前副本的同步到的最后一个消息的offset当Follower副本成功从Leader副本拉取消息并更新到本地的时候Follower副本的LEO就会增加

  HW(HighWatermark)和LEO与上面的ISR集合紧密相关HW标记了一个特殊的offset指的是所有ISR集合中最小的LEO位置当消费者处理消息的时候只能拉取到HW之前的消息HW之后的消息对消费者来说是不可见的HW也是由Leader副本管理当ISR集合中全部的Follower副本都拉取HW指定消息进行同步后Leader副本会递增HW的值通过多副本以及HW的同步保证了可靠性消费

  Kafka权衡了同步复制和异步复制通过加入ISR集合通过动态的管理副本集合避免所有副本同步复制带来的延迟过高问题利用HW来保证当Leader副本所在的Broker出现问题时此时消费Follower副本消息的一致性

在简单概念介绍完以及分析过kafka-producerkafka-replica-serverkafka-fetch后做一下从数据同步侧是如何保证可靠性问题

1.多副本机制

  通过一个分区多副本机制一个Leader副本其余都为Folloer副本每个副本都存在于不同的Broker上当Leader出现问题就进行故障转移在剩下的副本中选举新Leader来保证数据的可用性

2. ISR集合

  通过定义ISR集合实现分布式系统下的数据不丢失就像Zookeeper的大于一半的方式kafka通过定义ISR集合在producer生产消息过后需要ISR集合中的所有副本都同步此次数据后才确认这次生产的消息是成功的那么当Leader节点出故障后就可以从ISR集合中选出新Leader来保证已经生成的消息不会丢失同时通过动态的ISR集合的伸缩当追赶上Leader的LEO就将其加入到ISR中如果一个副本的lastCaughtUpTime < replica.lag.time.max.ms并且Follower LEO < Leader LEO那么也会被认为是失效副本从而踢出ISR中等待重新追赶上Leader

3. LEO与HW

  对于Partiton的每个副本而言其Log都有一个Log End Offset简称LEO而HW指的是Partition的所有副本中最小的LEO通过Replica Fetch Request同步Leader数据后就会及时的更新Leader的HW通过这种方式就很好的保证了数据可见的一致性因为不是每个Broker的状态都是一样的有的副本同步的比较慢从而每个副本的LEO可能是不一样的那么只有HW之前的消息对consumer是可见的这样的话当Leader失效重新选举Leader后就还可以保证只有HW之前的消息是可见的保证了数据的一致性因为有可能最后只剩一个副本当选新的Leader假设这个副本的LEO小于之前的Leader的LEO如果不以HW作为可见那么就会出现消息丢失的问题