1、整体流程
流程图
词汇
- topic:主题
- producer:生产者
- consumer:消费者
- consumer-group:消费者组
- offset:偏移量
- follower:副本
要点概述
- kafka是以topic进行分类的,由producer生产数据发送到topic,再被consumer进行消费,同时offset会记录每个分区的消费进度,就算中途挂掉了,下次也会从offset开始继续消费
- 每个topic可以有多个分区,每个分区可以配置1个或多个副本,形成leader-follower的关系,leader和follower不会在同一个节点上(这点和Elasticsearch类似)
- 每个分区只能被一个consumer消费,如果consumer数量比分区还多,会存在部分consumer闲置,没有数据可以消费
2、生产者
2.1、消息匹配分区
根据发送消息时是否指定partition和key,消息进入的partition策略也不同
指定partition | 指定key | 结果 |
---|---|---|
Y | / | 消息直接进入指定的partition |
N | Y | 将key的hash值,与partition数目相除与余数,结果就是匹配的分区 即:hash(key) % partitionCount |
N | N | 第1次生成随机数获取partition,后面递增+1,即每个partition轮流发送 |
2.2、ISR
- kafka的分区leader维护一个ISR列表,记录和leader保持同步的follower集合。
- 当ISR中的follower完成数据的同步之后,leader就会给producer发送ack。
- 如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。
- Leader发生故障之后,就会从ISR中选举新的leader。
如下图,follower1、2、3组成ISR,follower-4因为同步异常而被剔除。
2.2、Ack
producer发送消息后,leader将消息同步给follower,然后返回ack给producer,表示消息已收到,此时才可以继续发送下一条消息。
kafka提供了以下3种ack级别:
- 0:leader接收到消息马上返回ack,此时可能还没有写入磁盘,可能丢失数据
- 1:leader将消息写入磁盘后,马上返回ack,此时可能还没同步follower,同样可能丢失数据
- -1(all):leader和follower都将数据写入磁盘后,返回ack。但是如果在写入磁盘后,ack尚未发送,此时leader发生故障,会导致数据写入重复
3、消费者
3.1、消费方式
consumer采用pull方式主动从broker拉取数据,此时会传入timeout参数,如果当前没有数据可消费,consumer会等待一段时间,直到timeout超期才返回
3.2、分区分配方式
1个topic有多个partition,1个consumer-group有多个consumer,这其中就涉及到partition的分配问题。kafka提供2种分配方式:Range和RoundRobin
Range范围分配
原理是将partition数/consumer数,来决定每个consumer分配几个partition。如果除不尽,则前面几个consumer会多1个partition。
例如:当前有10个partition,3个consumer,则分配结果如下:
consumer | partition |
---|---|
consumer-0 | 0,1,2,3 |
consumer-1 | 4,5,6 |
consumer-2 | 7,8,9 |
RoundRobin轮询分配
顾名思义,就是轮询每个consumer,逐一分配。
还是用上面的例子:当前有10个partition,3个consumer,则分配结果如下:
consumer | partition |
---|---|
consumer-0 | 0,3,6,9 |
consumer-1 | 1,4,7 |
consumer-2 | 2,5,8 |
4、Topic文件存储原理
要点概述
-
文件存储路径由server.properties的log.dirs配置
-
logs目录下每个分区会自动创建一个分区文件夹,文件夹名为
主题名称-分区号
,例如test-0、test-1、test-2 -
分区文件由index和log文件组成,log文件存储message数据,index文件存储每条message对应的offset偏移量。如下图:
-
index和log文件的命名,是由log文件第一条message在整个partition所处的顺序决定的