kafka的消息消费机制、consumer的负载均衡、文件存储机制

这篇笔记的内容回答了上篇 Kafka运行机制与各组件详解 剩余的问题(这些内容来自于学过的学习资料)。

1、消息的消费机制(回答有序消费问题)
主要说的是消费者与目的地的关系(comsumer与topic的关系)
本质上kafka只支持Topic;
(1)每个group中可以有多个consumer,每个consumer属于一个consumer group;
通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高”故障容错”性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。
(2)对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;
那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个”订阅”者。
(3)在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
一个Topic中的每个partitions,只会被一个”订阅者”中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。
(4)kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。
kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。
注:
这是个伪命题
如果要全局有序的,必须保证生产有序,存储有序,消费有序。
由于生产可以做集群,存储可以分片,消费可以设置为一个consumerGroup,要保证全局有序,就需要保证每个环节都有序。
只有一个可能,就是一个生产者,一个partition,一个消费者。这种场景和大数据应用场景相悖。

2、kafka的consumer的负载均衡策略
注:这里来自于网络,但是现在还没看源码,但是感觉算法是有问题的。
当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提升topic的并发消费能力,步骤如下:(这个图网上流传很广,但是画错了,具体见笔记)
1、假如topic1,具有如下partitions: P0,P1,P2,P3
2、加入group中,有如下consumer: C1,C2
3、首先根据partition索引号对partitions排序: P0,P1,P2,P3
4、根据consumer.id排序: C0,C1
5、计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
6、然后依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]
这里写图片描述
注:首先partition在2台机器上的分布应该是第一台上:P0,P2;第二台:P1,P3(根据key的hash来取,参考Kafka运行机制与各组件详解 )。

3、文件的存储机制
(1)、kafka文件存储基本结构

  • 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。
    如,前篇里面的orderMq这个topic对应的partitions在三台机器上名称分别为
drwxr-xr-x. 2 root root 4096 1121 22:25 orderMq-0
drwxr-xr-x. 2 root root 4096 1121 22:25 orderMq-2
drwxr-xr-x. 2 root root 4096 1114 18:45 orderMq-1
drwxr-xr-x. 2 root root 4096 1114 18:45 orderMq-2
drwxr-xr-x. 2 root root 4096 1121 22:25 orderMq-0
drwxr-xr-x. 2 root root 4096 1121 22:25 orderMq-1

注:重复的是副本,partition是为orderMq-0,orderMq-1,orderMq-2
- 每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。默认保留7天的数据。
如orderMq-0目录下(index和log为后缀名的文件合称就是segment 文件)

[root@mini3 orderMq-0]# ll
总用量 4
-rw-r--r--. 1 root root 10485760 11月 21 22:31 00000000000000000000.index
-rw-r--r--. 1 root root      219 11月 22 05:22 00000000000000000000.log

这里写图片描述
-每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。(什么时候创建,什么时候删除)

(2)kafka的segment 文件

  • Segment file组成:由2大部分组成,分别为index file和data file,此2个文件一一对应,成对出现,后缀”.index”和“.log”分别表示为segment索引文件、数据文件。
    这里写图片描述
  • Segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。
  • 索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。
    这里写图片描述
    3,497:当前log文件中的第几条信息,存放在磁盘上的那个地方
    上述图中索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。
    其中以索引文件中元数据3,497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。
    (3)、kafka查找message
    读取offset=368776的message,需要通过下面2个步骤查找。
    这里写图片描述
    第一步:查找segment file
    00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0
    00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1
    00000000000000737337.index的起始偏移量为737338=737337 + 1
    其他后续文件依次类推。
    以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。当offset=368776时定位到00000000000000368769.index和对应log文件。

第二步:通过segment file查找message
当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址
然后再通过00000000000000368769.log顺序查找直到offset=368776为止。

猜你喜欢

转载自blog.csdn.net/qq_37334135/article/details/78598289