Kafka 杂谈

quickstart

  • Broker: Kafka集群包含一个或多个服务器,这种服务器被称为broker
  • Topic: 每条发布到Kafka集群的消息都有一个类别,这个类别被称为topic。(物理上不同topic的消息分开存储,逻辑上一个topic的消息虽然保存于一个或多个broker上但用户只需指定消息的topic即可生产或消费数据而不必关心数据存于何处)
  • Partition: parition是物理上的概念,每个topic包含一个或多个partition,创建topic时可指定parition数量。每个partition对应于一个文件夹,该文件夹下存储该partition的数据和索引文件
  • Producer: 负责发布消息到Kafka broker
  • Consumer: 消费消息。每个consumer属于一个特定的consuer group(可为每个consumer指定group name,若不指定group name则属于默认的group)。使用consumer high level API时,同一topic的一条消息只能被同一个consumer group内的一个consumer消费,但多个consumer group可同时消费这一消息。
kafka参数的配置需要在可用性和数据一致性之间进行权衡
acks 参数

预备知识: 每个partition都有1到多个副本,这里假设有1个副本,多个副本冗余的机制保证了kafka的高可用. client端写数据时先写到某个partition的leader, 然后对应partition的follower会发送请求给leader,要求获取最新的数据,然后leader把最新的数据同步给follower落盘,完成数据同步.此过程是follower周期性从leader拉pull数据. 如果发现某个follower落后leader的数据量大于设置的 replica.lag.max.messages的数量或者replicas响应的时间大于设置的replica.lag.time.max.ms的时间,则会把该follower从leader的同步列表中移除,从而避免了影响整体写数据的延迟的增加. 注意: replica.lag.max.messages 不能太小也不能太大,小了可能由于client批量发送个大量的数据,也可能正常存活的follower可能由于GC导致的延迟被leader移除同步列表,该follower再次找leader拉去数据时又重新加入同步列表,可能一直反复。 大了,可能造成丢失数据的可能. 时间的设置类似.

ISR机制全称是In-Sync Replicas 保持同步的副本的列表 min.insync.replicas配置ISR中的副本个数

acks参数是在KafkaProducer客户端里进行设置的

acks常见设置为0, 1, all
acks参数值 含义
0 指kafkaProducer的客户端只要把消息发送出去,就认为消息发送成功.不管partitionLeader是否已经落盘,存在丢失数据的可能.比如消息发出去后,还未到leader机器,机器断电了,会造成该数据丢失.
1 默认值值kafkaProducer客户端发送消息后,并且partitionLeader接收到了消息并且已经落盘,则认为消息发送成功.可能未同步到follower. 如果还未同步到follower,leader发生宕机,将导致消息丢失.
all 指的是Leader接收消息后还要求ISR列表中的follower跟leader保持最新消息的同步落盘完成,才认为该消息发送成功.如果follower过多,整个过程会很慢,需要合理设置副本的数量. 如果ISR中只有一个leader,也可能导致数据丢失,所以一定至少有一个及以上的副本
kafka多个partition如何进行分区选主的? 就是ISR中的leader宕机了,剩下的partition重新选举的过程
  • 几个概念: AR、ISR、OSR、LEO、HW这些信息都被保存在Zookeeper中。
    • ISR (In-sync Replica) : leader同步的follower列表, 如果被踢出该列表则进入 OSR
    • OSR (out-sync Replica) : 从ISR中被踢出的follower
    • AR (Assigned Replica) : ISR + OSR
    • LEO (LogEndOffset) : 分区最新数据的offset,当leader新写入数据后,立即更新LEO
    • HW (HighWatermark) : 只有写入的数据被同步到所有的ISR中的副本后,数据才认为已提交,HW更新到该位置,HW之前的数据才可以被消费者访问,保证没有同步完成的数据不会被消费者访问到。相当于所有副本同步数据标识位。在leader宕机后,只能从ISR列表中选取新的leader,无论ISR中哪个副本被选为新的leader,它都知道HW之前的数据,可以保证在切换了leader后,消费者可以继续看到HW之前已经提交的数据。所以LEO代表已经写入的最新数据位置,而HW表示已经同步完成的数据,只有HW之前的数据才能被外界访问。
    • HW截断机制: 如果leader宕机,选出了新的leader,而新的leader并不能保证已经完全同步了之前leader的所有数据,只能保证HW之前的数据是同步过的,此时所有的follower都要将数据截断到HW的位置,再和新的leader同步数据,来保证数据一致。当宕机的leader恢复,发现新的leader中的数据和自己持有的数据不一致,此时宕机的leader会将自己的数据截断到宕机之前的hw位置,然后同步新leader的数据。宕机的leader活过来也像follower一样同步数据,来保证数据的一致性。

kafka选择分类

  • 控制器的选举 kafka集群中有多个broker,其中一个broker会被选举为控制器(kafka controller),负责管理整个集群中所有分区和副本的状态等工作. 比如某个分区leader副本出现故障,则由控制器为该分区选举新的leader副本。在比如当检测到某个分区ISR集合发生变化时,由控制器负责通知所有broker更新元数据信息。kafka controller选举依赖zookeeper实现, 如果那个broker能成功创建/controller 这个临时EPHEMERAL节点,则成为kafka controller.
  • 分区leader的选举 当发生leader宕机或者被优雅关闭或者新创建等等时,会发生分区leader选举情况。基本思路是从AR集合中的副本中顺序查找第一个存活的副本,并且这个副本在ISR集合中. 一个分区的AR集合在分配的时候就被指定了,并且只要不发生重新分配情况,集合内部副本数据保持不变,而ISR集合顺序可能会改变.
  • 消费之相关的选举 当需要消费的时候租协调器就要为消费组内的消费者选举一个消费者的leader。分两种情况,如果没有,则第一个加入消费组就是leader。第二,某一时刻消费组leader退出,重新随机选举一个leader.
类似MySQL、Zookeeper、Redis的Leader/Follower(或者称Master/Slave)架构,从节点都是可以提供读服务的。为什么Kafka设计成follower副本不能提供任何服务,只是单纯地作为leader的冷备呢?
  • Follwer只有一个任务从Leader中Pull数据进行异步同步,或者做重新选主
  • 消费延迟:如果Follwer提供读,需要先从LeaderPull过来然后再提供读数据服务,存在延迟。而MySQL/Redis等一条数据被插入后,立即被查询的可能性较小。
  • 数据一致性:如果副本较多,由于leader和follower之间采用异步复制,就可能出现不同follower副本之间消息不一致,这样Consumer端就可能出现消费混乱的情况。

研究资料