kafka的工作机制

本文详细介绍了Kafka的工作机制,包括kafka架构、topic与partition的解析,以及消息流处理中的ISR机制和高可用策略。讨论了producer、broker、consumer、consumer group的角色,以及offset的管理,强调了Kafka如何通过replica和ISR实现数据高可用和避免数据丢失。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kafka架构

kafka拓扑结构说明

kafka拓扑结构

  • producer
    消息生产者,发布消息到kafka集群的终端或服务
  • broker
    kafka集群中包含的服务器,代理人,消费转发服务
  • topic
    每条发布到kafka集群的消息所属的类别,即kafka是面向topic的
  • partition
    partition是物理上的概念,每个topic包含一个或多个partition,kafka分配的单位是partition
  • consumer
    从kafka集群中消费消息的终端或服务
  • consumer group
    high-level consumer API中,每个consumer都属于一个consumer group,每条消息只能被consumer group中的一个consumer消费,但可以被多个consumer group的consumer消费,即组间数据是共享的,组内数据是竞争的
  • replica
    partition的副本,保障partition的高可用
  • leader
    replica中的一个角色,producer和consumer只跟leader交互
  • follower
    replica中的一个角色,从leader中复制数据
  • controller
    kafka集群中的其中一个服务器,用来进行leader election以及各种failover
  • zookeeper
    作为分布式协调服务,kafka通过zookeeper来存储集群的元数据信息

topic与partition说明

topic结构
上图是topic主题的剖析图
生产者消费者工作模式
上图是生产者与消费者读写模式

  • topic
    每条发布到kafka集群的消息都有一个类别,这个类别被称为topic主题
  • partition
    partition是物理上的概念,每个topic包含一个或多个partition
  • topic在逻辑上可以被认为是一个queue,每条消息都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里
  • 为了使得kafka的吞吐率可以线性提高,物理上把topic分成一个或多个partition,每个partition在物理上对应一个文件夹,该文件夹存储了这个partition的所有消息和索引文件,如下所示:
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 testtopic-0
cd testtopic-0查看所有文件
-rw-r--r--. 1 root root 10485760 Jan 26 00:57 00000000000000000000.index
-rw-r--r--. 1 root root      213 Jan 26 01:19 00000000000000000000.log
-rw-r--r--. 1 root root 10485756 Jan 26 00:57 00000000000000000000.timeindex
-rw-r--r--. 1 root root        8 Jan 26 00:57 leader-epoch-checkpoint
  • 每条消息都被append到该partition中,属于顺序写磁盘,这样效率非常高
  • 对于传统的mq而言,一般会删除已经被消费的消息,而kafka集群会保留所有的消息,无论有没有被消费。当然,因为磁盘限制,不可能永久保留所有数据,实际上也没有必要,因此kafka提供了两种删除策略来删除旧数据。一是基于时间,二是基于partition文件大小。可在server.properties中设置,如下所示:
#可被删除的日志文件的最小年龄,单位:小时
log.retention.hours=168
#日志段文件的最大大小。当达到这个大小时,将创建一个新的日志段,单位:字节
log.segment.bytes=1073741824
#检查日志段以查看是否可以根据保留策略删除它们的间隔,单位:毫秒
log.retention.check.interval.ms=300000
#如果设置了log.cleaner.enable = true,则将启用清理程序,然后可以标记单个日志以进行日志压缩
log.cleaner.enable=false

kafka消息流处理

示意图:
消息流处理示意图

  • producer先从zookeeper的/brokers/topics/testtopic/partitions/0/state节点找到该partition的leader
  • producer将消息发送给该leader
  • leader将消息写入本地log文件
  • followers从leader pull消息,写入本地log后向leader发送ACK
  • leader收到所有ISR(In-Sync Replicas机制)中的replica的ACK后,增加HW(high watermark,最后commit的offset)并向producer发送ACK

什么是ISR?

  • leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护
  • 如果一个flower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除
  • 当ISR中所有Replica都向Leader发送ACK时,leader才commit
  • 比如:有三个副本 ,编号是① ② ③ ,其中② 是leader ① ③是follower。假设在数据同步过程中,①跟上leader,但是③出现故障或没有及时同步,则① ②是一个ISR,而③不是ISR成员。后期在leader选举时,会用到ISR机制,会优先从ISR中选择leader

kafka高可用机制

概述:

  • 同一个partition可能会有多个replica,对应server.properties配置项中的default.replication.factor=N
  • 没有replica的情况下,一旦broker宕机,其上所有partition的数据都不可被消费,同时producer也不能再将数据存于其上的partition
  • 引入replication之后,同一个partition可能会有多个replica,而这是需要在这些replica之间选出一个leader,producer和consumer只与这个leader交互,其他replica作为follower从leader中复制数据

leader failover:

  • 当partition对应的leader宕机时,需要从follower中选举出新的leader。在选举新的leader时,一个基本的原则是,新的leader必须拥有旧的leader commit过的所有消息
  • 由写入流程可知ISR里面的所有replica都跟上了leader,只有ISR里面的成员才能选举为leader。对于f+1个replica,一个partition可以在容忍f个replica失效的情况下保证消息不丢失。比如:一个分区有5个副本,挂了4个,剩一个副本,依然可以工作(注意:kafka选举不同于zookeeper,用的不是过半选举)

当所有replica都不工作时,有两种可行的方案:

  • 等待ISR中的任一个replica活过来,并选举它为leader。这样可保证数据不丢失,但时间可能相对较长
  • 选举第一个活过来的replica(不一定是ISR成员)作为leader。这样无法保证数据不丢失,但相对不可用的时间较短,kafka默认使用该方案。

kafka offset机制

kafka消费者的offset存储机制,consumer在从broker读取消息后,可以选择commit,该操作会在kafka中保存该consumer在当前partition中读取的消息的offset。该consumer下一次再读取当前partition时会从下一条开始读取,通过这一特性可以保证同一消费者从kafka中不会重复消费数据。
执行:sh kafka-console-consumer.sh --bootstrap-server node01:9092 --topic testtopic --from-beginning
然后,进入kafka-logs目录查看,会发现很多个目录,这是因为kafka默认会生成50个_consumer_offsets的目录,用于存储消费者消费的offset位置。如下所示:

drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-0
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-10
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-12
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-14
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-16
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-18
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-2
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-20
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-22
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-24
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-26
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-28
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-30
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-32
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-34
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-36
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-38
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-4
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-40
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-42
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-44
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-46
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-48
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-6
drwxr-xr-x. 2 root root 4096 Jan 26 00:57 __consumer_offsets-8

注意:如果有多个broker节点,offsets目录会平均分布到多个节点上,kafka会使用以下计算公式计算该消费者group位移保存在_consumer_offsets的哪个目录上:Math.abs(groupID.hashCode())%50

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值