相识满天下,知心能几人。
—— 明·冯梦龙
本文已同步掘金平台,图片依然保持最初发布的水印(如CSDN水印)。(以后属于本人原创均以新建状态在多个平台分享发布)
前言
话说今天是1024,程序猿(媛)节,在“屌丝”盛行之时,称为屌丝节。随着全面小康社会的展望,为了彰显IT界码农的身份,程序猿(媛)由屌丝晋升为“爱码仕”,也许是为了与双十一与时俱进吧。
以上纯tx! 还是来点干货吧…
Kafka架构
从上图可以看出,Kafka主要有生产者、broker、消费者群、消费者、zookeeper概念,各个概念一一来讲解。
Producer
注:生产者
生产者,以ProducerRecord为对象推送给Kafka broker,ProducerRecord的主要以topic主题、分区partition(可选)、key(可选)、消息体,timestamp(可选)。
源码如下:
Topic
注:主题
Kafka以主题topic的方式推送消息,一个主题可以被多个消费者消费。主题里的消息体又以多个分区partition来存储的
Partition
注:分区
- 如果ProducerRecord的partition指定了某个分区,那么消息体存储到指定的分区里
- 如果ProducerRecord的partition(其实就是分区号),如果没有指定分区器,则使用默认分区器DefaultPartitioner来计算,然后根据ProducerRecord的key来计算
- 如果key为空,则以轮询的方式来给主题下的各个可用分区来发送消息(注意这里,是可用分区)。
- 如果key不为空,则根据hash算法(采用MurmurHash2算法,具备高运算性能及低碰撞率)计算分区号,相同的key会分配到同一个分区。
Offset
注:偏移量
每个分区都有一个Offset,这个Offset就是这个生产者的Offset,并且是分区的最大的offset。
当然还有消费者偏移量。下一期,我会详细介绍。
Segment
一个分区其实由多个大小相等的Segment(段)组成,每个段Segment file 的消息数量可以不相同,这样方便删除旧的Segment
- 其存储结构
生产者发送消息到主题后,消息会根据分区策略被分配到多个分区里,Kafka broker会把消息往分区里的最后一个Segment里添加消息,如果Segment消息的数量达到了阈值或时间超时时,Segment上的消息会flush到磁盘里,flush的消息才会被消费者消费,如果Segment的消息大小达到一定值时,就不会往旧的Segment写入,而是新建一个Segment。 - Segment file 组成
- index file,后缀名.index,表示Segment的索引文件,对应Segment第一个消息
- data file , 后缀名.log, 表示数据文件
以上两个文件成对出现
- Segment 命名规则
- Partition的第一个Segment从0开始
- 后面的Segment都是从上一个全局的Partition的最大Offset
- 数值最大为64位long大小,19位数字字符长度,没有数字用0填充。
- 每个segment中存储很多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射
- 上图查找offset=1001过程:
- 先查找Segment file文件,00000000000000000000.index为全局Partition 的Segemtnt起始文件,那么offset=1001偏移量的消息的Segemnt文件名为00000000000000001001.index
- 然后找到对应数据文件00000000000000001001.log,其起始偏移量为1001+1=1002,其他偏移量也是如此查找(二分查找文件名)
- 定位index文件物理位置Position,其直接映射内存物理地址,然后按照顺序查找到对应的00000000000000001001.index.
Consumer Group
注:消费群组
多个消费者在同一个组里,成为消费者群。一个分区的消息,只能被同一个消费群里的某一个消费者消费,但能被其它消费者群的某一个消费者消费。
#Consumer
注:消费者
消费群组:消费者 = 1:1
broker消费者分区分配:所有分区的消息被一个消费者消费
消费群组:消费者 = 1:N,且分区数量>消费者
broker消费者分区分配过程:p0->c1消费; p1->c2消费; p2->c1消费
消费群组:消费者 = 1:N,且分区数量=消费者
broker消费者分区分配过程:p0->c1消费; p1->c2消费; p2->c3消费
消费群组:消费者 = 1:N,且分区数量<消费者
broker消费者分区分配过程:p0->c1消费; p1->c2消费; p2->c3消费 ; c4不消费。
因为同一个消费群组里,一个分区只能被其下的一个消费者消费。为什么要这样,其实想想很简单,避免重复消费。
消费群组:消费者 = N:N
broker消费者分区分配过程:
消费群组group1:p0->c1消费; p1->c2消费; p2->c1消费;
消费群组group2:p0->c1消费; p1->c2消费; p2->c3消费;
消费群组group3:p0->c1消费; p1->c2消费; p2->c3消费 ; c4不消费。
后续
下期预告,敬请关注:
(三)消息队列-Kafka偏移量(Offset)(相念)
学无止境,时不待我!