一个故事理解消息队列 - 下
这是一篇迟到一月有余的文章。
在 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 列表。
版权声明: 本文为 InfoQ 作者【老张】的原创文章。
原文链接:【http://xie.infoq.cn/article/9d4cba8ab5edf1a5cb48555ea】。文章转载请联系作者。
评论