# 介绍
在系统中随着业务的发展,我们要做异步、要做解耦、要做流的处理、要做可靠传输等等。消息队列是必不可少的。今天给大家讲解下消息列队中用的比较多的Kafka。
Kafka是一个高吞吐量、分布式、基于发布/订阅的消息系统。主要组件有:
-
broker
Kafka的服务器,复制消息的存储和转发。
-
topic
消息类别,Kafka是按照topic来进行分类消息的。
-
partition
是topic上分区,一个topic可以包含多个partition,topic消息保存在各个partition上。
-
offset
消息在日志中的位置,你可以理解为消息在partition上的偏移量,也代表该消息的唯一序号。
-
Producer
消息的生产者。
-
Consumer
消息的消费者。
-
Consumer Group
消费者分组,每一个consumer必须属于一个Group。
-
Zookeeper
保存着集群broker、topic、partition等meta数据;负责broker故障发现、partition leader选举、负载均衡等功能。
如下图所示
# 数据存储设计
-
partition的数据文件
partition中的每条message包含了三个属性:offset,MessageSize,data,其中的offset表示Message在partition中的偏移量,offset不是该Message在partition数据库文件的实际存储位置。而是一个逻辑上的值,它唯一确定了partition中的一条消息,可以认为offset是partition中Message的Id;MessageSize表示消息内容data的大小;data是Message的具体内容。
-
数据文件分段segment
partition物理上来说是由多个segment文件组成,每个segment文件的大小相等,顺序读写。比如有100条Message,它们的offset是从0到99。假设将数据文件分成5段,第一段为0-19,第二段为20-39,以此类推,每段放在一个单独的数据文件里面每个segment数据文件以该段中最小的offset命名,文件扩展名为.log。这样在查找指定offset的Message时候,用二分查找就可以定位到该Message在哪个segment数据文件中。
-
数据文件索引
Kafka 为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩 展名为.index。index 文件中并没有为数据文件中的每条 Message 建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以 将索引文件保留在内存中。
# 生产者主要功能
-
负载均衡
前面我们知道消息topic是由多个partition组成,并且partition发布在不同的broker上面,为了有效利用 broker集群的性能,提高消息的吞吐量,producer可以通过随机或者 hash 等方式,将消息平均发送到多个partition 上,以实现负载均衡。
-
批量发送
为了提高消息吞吐量,Producer 端可以在内存中合并多条消息后,以一次请求的方式发 送了批量的消息给 broker,从而大大减少 broker存储消息的 IO 操作次数。但也一定程度上影响了消息的实时性,相当于以时延代价,换取更好的吞吐量。
-
压缩
Producer 端可以通过 GZIP 或 Snappy 格式对消息集合进行压缩。Producer 端进行压缩之后,在 Consumer 端需进行解压。压缩的好处就是减少传输的数据量,减轻对网络传输的压力,在对大 数据处理上,瓶颈往往体现在网络上而不是 CPU(压缩和解压会耗掉部分 CPU 资源)。
# 消费者设计
同一 Consumer Group 中的多个 Consumer 实例,不同时消费同一个partition,等效于队列模 式。partition 内消息是有序的,Consumer 通过 pull 方式消费消息。Kafka 不删除已消费的消息,对于 partition,顺序读写磁盘数据,以时间复杂度 O(1)方式提供消息持久化能力。