一个故事理解消息队列-下
这是一篇迟到一月有余的文章。
在7月18号,我用了一个故事作为案例,介绍了消息队列的基本功能和应用场景。本打算第二天介绍消息队列的主要功能特性的,由于文章排期等其他因素影响,故更新搁置了。
这篇文章,接上篇《一个故事理解消息队列-上》,以Kafka为例,为大家介绍消息队列的主要功能特性。
Kafka核心组件
在介绍消息队列的功能特性之前,先介绍一下Kafka的核心组件。其工作原理如下图所示:
PS:懒得自己画图了,网上随便找的,网图侵删。
Producer(生产者):发送消息的一方,负责将消息发送到Kafka的主题(Topic)。
Consumer(消费者):接受消息的一方,订阅主题并处理其中的消息。
Topic(主题):可将其理解为消息类型,Kafka中的消息以Topic为单位进行划分,生产者将消息发送到对应的Topic,消费者订阅不同Topic的消息并进行消费处理。
Broker(代理):Kafka服务集群中一台服务器就是一个broker,支持水平扩展,同一Topic消息可以分布在多个broker中。
Partition(分区):主题的物理分片,主要作用是提高并行处理能力。
Replica(副本):Kafka中同一Partition的数据可以在多个Broker上存在,一般主副本对外提供读写服务,Controller只充当备份存储角色。当主副本所在的broker发生异常,Kafka会进行主从选举切换来保障其高可用。
ZooKeeper:Kafka集群的元数据进行管理,以及承担分布式调度工作。
数据存储机制
首先要明确一点,Kafka中的消息存储于文件系统之中。
Kafka的数据存储机制是采用顺序写入磁盘的方式,来提高数据写入性能。可能有些同学会认为数据存储于磁盘中,相比于内存来说速度会慢很多,但实际上只要磁盘结构设计合理,它的速度甚至可以和网络速度媲美。
在Kafka中,Topic是一个逻辑概念,主要面向生产者和消费,物理上的数据存储其实是Partition(分区)。
Partition中的消息被存储在多个Segment文件中,每个Segment文件由一组连续消息组成。Segment文件通过索引和日志文件进行管理,索引文件记录每条消息在日志文件中的偏移量。
省流概括——Kafka的存储机制主要有如下几个特点:
- 顺序写入:通过顺序写入提高写入速度和磁盘利用率。
- 索引机制:通过索引快速定位消息,提高读取速率。
- Segment文件:消息采用分段存储,便于管理和清理。
- 日志清理策略:支持基于时间和大小的日志清理策略,确保存储空间有效利用。
顺序写入机制
Kafka是按照顺序写入机制来存储消息的,消息被存储于多个Partition(分区)中,每个分区都是一个有序且不可变的队列。
生产者将消息发送到分区时,Kafka按照消息发送顺序将其追加到分区末尾。消费者按照订阅逻辑读取消息时,也是按照消息的存储顺序来逐条读取。因此,消息的顺序可以严格保证。
对于某些特定业务场景来说,消息的有序性特别重要,比如银行金融和电商业务中的订单消息处理。
针对这种特定的业务场景,还分为全局有序和局部有序两种类型。
全局有序:即一个Topic中的所有消息都按照写入顺序进行读取消费。要实现这一特性,则需要保证一个Topic中只能存在一个Partition,且对应的消费者也要通过单线程等方式来保证消费顺序。
局部有序:同一个Topic中的消息,只需要满足某个业务字段按照消息生产顺序消费即可。
比如电商业务中的订单消息中包含orderid字段,只需要在消息写入时指定Partition Key,对其进行Hash计算,根据计算结果决定放入哪个Partition。然后订阅该消息的消费者按序进行读取消费即可。
这种情况下,同一个Topic下依然可以存在多个Partition,进而可以提升整体吞吐量。
高可用容错机制
Kafka提供了消息持久化、重试机制和确认机制,确保消息不会丢失或重复处理,增强系统的容错能力。在Kafka中,通过如下几种机制来实现高可用和容错性:
- 副本机制:每个Partition有多个副本,主副本负责读写操作,其它副本定期从主副本同步数据。当主副本发生故障时,会从其他副本中选举新的主副本,即主从选举机制。
- AC机制:生产者发送消息时,可以设置ACK来确保消息被成功写入主副本和其他副本,保证数据不丢失。
- ISR(In-Sync Replica)机制:在Kafka中维护一个ISR列表,记录当前与主副本保持同步的副本,只有在列表中的副本才会参与主从选举。
- ZooKeeper协调:ZooKeeper在Kafka中的作用就是进行分布式协调,管理元数据和集群状态。
既然说到了高可用,那就不能不提高性能了。Kafka的扩展性主要体现在如下几个方面:
- 水平扩展:增加Broker节点,扩展Kafka集群的存储和处理能力。
- Partition扩展:通过增加Partition(分区)数量,提高Topic的并行处理能力。
- 动态配置:Kafka支持在运行时动态调整部分配置,如Topic分区数量和副本因子。
ZooKeeper作用
Kafka通过ZooKeeper进行分布式协调、管理员数据和集群状态。在Kafka中,通过将Broker、Topic和Partition元数据信息存储在Zookeeper中,并在其上建立相应的数据节点,监听节点变化。
其中,ZooKeeper主要承担如下几点职责:
- 状态监控:监控集群运行状态,保证系统一致性和高可用。
- 分布式协调:负责Broker注册发现、主从选举、负载均衡等功能。
- 元数据管理:存储Kafka元数据,包括Broker列表、Topic和Partition信息、ISR列表。