kafka架构:

1,生产者producer

2,代理broker

3,消费者consumer

三者作用:kafka给生产者和消费者提供注册接口,生产者将数据发送到broker,broker负责将数据进行中间缓存和分发,分发注册到消费者。

kafka设计要点:

1,kafka直接采用linux文件系统的cache进行缓存数据。

2,采用linux的zero-copy提高发送性能。(传统数据发送需要发送4次上下文切换,采用sendfile系统调用之后,数据直接在内核态进行交换,减少了上下文切换2次,提高了很大的数据发送性能,存储代价为o1)

组件流程:

1,kafka是以topic进行消息管理,每个topic包含多个partition,每个part对应一个逻辑log,该逻辑log是由segment组成。

2,每个segment中存储多条消息,消息id是由其逻辑位置决定的,可以从消息id直接定位到消息的存储位置。

3,每个part在内存中对应一个index,是用来记录每个segment中第一条消息的偏移。

4,发到topic的消息会被均匀的分布到多个part上(随机或者用户指定回调函数)。

5,broker收到的发布消息后往对应part的最后一个segment上添加消息,当某个segment上的消息到达配置值或者时间超过阈值,segment的消息就会flush到磁盘上。

6,只有flash到磁盘上的消息才能被订阅,segment达到一定大小后,broker将会创建新的segment

7,broker和producer之间是没有负载均衡的。

8,broker和consumer之间通过zookeeper之间进行负载均衡。所有的broker和consumer都会在zookeeper中进行注册,zookeeper会保存他们的一些元数据,如果某一个变化,其他broker和consumer都会得到通知。

kafka消息存储的方式:

1,topic是发布消息的类别,对于每个topic,kafka集群都会维护这一分区的log。

2,每个分区都是一个有序的,不可变的消息队列,并且可以持续添加。分区中的消息都被分配了一个序列号,称为偏移量。每个分区中的偏移量都是唯一的。

3,采用分区的两个目的:一是处理更多的消息而不受单台服务器的限制,二是分区可以作为并行处理数据的单元。

4,kafka会为每个分区创建一个文件夹,命名的方式为topicName-分区序号

5,分区是由多个segment组成,每个segment以该内的第一条消息的偏移量命名,以.log为后缀。

6,同时,分区中还有一个索引文件,标明了每个segment下包含的offset的范围,以.index后缀。

索引文件与日志文件的内部关系:

1,索引文件存储大量元数据,日志文件存储大量消息。

2,索引文件中的元数据指向对应的日志文件中的物理偏移地址。(索引文件中3,497表示第三个message和它的消息物理偏移地址497).

3,segment的log文件是由多个message组成。segment的物理组成:8byte offset,4byte message size,4byte crc32,1byte 服务协议版本号,1byte独立版本标识,4byte key长度,实际消息数据。

如何通过offset查找message:

1,offset=368776的message

第一步:00000000000000000000.index表示最开始的文件,起始的offset为0,第二个文件0000000000000368769.index的起始偏移量为368770,第三个文件0000000000000737337.index,起始offset为737338。根据二分法查找定位到具体文件。

第二步:定位到文件在0000000000000368769.log中,根据物理存储位置在顺序查找。

2,segment的index file采取稀疏索存储方式,减少索引大小,通过linux的mmap接口可以直接进行内存操作。稀疏索引为数据文件的每个对应的message设置一个元数据指针,它比稠密索引节省存储空间,查找需要更多时间。

 主要代码解读:

一,Log包相关组件

1,LogManager

     管理broker上所有的logs(在一个log目录下),一个topic的一个partition对应一个log的子目录。日志管理器管理和维护多个路径下的日志文件,并且会自动比较不同路径下的文件数目,然后选择在最少的日志路径下创建新的日志。LogManager不会去尝试移动分区,并且会定期裁剪过量日志段。

2,Log

    日志类,以伴生对象方式提供。定义了一些类级别的变量,比如定义了一个日志文件的扩展名,索引文件的扩展名,要被删除文件的扩展名,临时文件扩展名等。

3,Log Segment

     Segment是一个逻辑概念,为防止log过大,需将log分成多个log segment。segment又分为俩部分:messageset文件和index文件,命名方式都是起始的offset。