这是我参与「第五届青训营」伴学笔记创作活动的第 16 天
1. 概述
我将主要介绍如下知识点:
- 什么是消息队列
- Kafka
2. 什么是消息队列
概念:
-
消息队列(MQ),是
保存消息的一个容器,本质是一个队列,这个队列需要支持高吞吐、高并发和高可用
业界消息队列对比:
-
Kafka:
- 分布式、分区的、多副本的日志提交服务,
在高吞吐场景下发挥较为出色
- 分布式、分区的、多副本的日志提交服务,
-
RocketMQ:
- 低延迟、强一致、高性能,在
实时场景中运用较广
- 低延迟、强一致、高性能,在
-
Pulsar:
- 是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离架构设计
-
BMQ:
- 和 Pulsar 架构类似,存算分离,初期定位是承接高吞吐离线业务场景,逐渐替换掉对应的 Kafka 集群
3. Kafka
3.1 如何使用 Kafka
-
第一步:首先需要创建一个 Kafka 集群
-
第二步:需要在这个集群中创建一个 Topic,并且设置好分片数量
-
第三步:引入对应语言的 SDK,配置好集群和 Topic 等参数,初始化一个生产者,调用 Send 方法,将你的 Hello World 发送出去
-
第四步:引入对应语言的 SDK,配置好集群和 Topic 等参数,初始化一个消费者,调用 Poll 方法,你将收到你刚刚发送的 Hello World
3.2 基本概念
-
Topic:
逻辑队列,不同的业务场景可以创建不同的 Topic -
Cluster:
物理集群,每个集群可以创建多个不同的 Topic -
Producer:
生产者,负责将业务消息发送到 Topic 中 -
Consumer:
消费者,负责消费 Topic 中的消息 -
ConsumerGroup:
消费者组,不同的消费者组进度互不干涉 -
Partition:通常 Topic 会有多个
分片,不同分片直接消息是可以并发来处理的,这样提高单个 Topic 的吞吐 -
Offset:
消息在 Partition 内的相对位置信息,可以理解为唯一ID,在 Partition 内部严格递增 -
Replica:
Partition 的副本,可用来容灾,这些副本有着不同的角色,分别是 Leader 和 Follower,Leader对外服务,Follower 异步去拉取 Leader 的数据进行一个同步,如果 Leader挂掉了,可以将 Follower 提升成 Leader 再对外进行服务 -
ISR:
同步中的副本,对于 Follower 来说,始终和 Leader 是有一定差距的,但当这个差距比较小的时候,我们就可以将这个 Follower 副本加入到 ISR 中,不在 ISR 中的副本是不允许提升成 Leader 的
3.3 Kafka 架构
在集群的基础上,还有一个模块是 ZooKeeper,这个模块其实是存储了集群的元数据信息,比如副本的分配信息等等,Controller 计算好的方案都会放到这个地方
3.4 从一条消息分析Kafka流程
一条消息从生产到消费是如何处理的,Producer端逻辑、Broker端逻辑、Consumer端逻辑:
下面将介绍一些可以帮助 Kafka 提高吞吐或者稳定性的功能:
3.4.1 Producer
- 批量发送
- 批量发送可以减少 IO 次数,从而加强发送能力
- 数据压缩
- 通过压缩,减少消息大小,目前支持 Snappy、Gzip、LZ4、ZSTD 压缩算法
3.4.2 Broker
-
消息文件结构
-
顺序写
- 采用顺序写的方式进行写入,以提高写入效率
-
偏移量索引文件
- 通过二分找到小于目标 offset 最大的索引位置,再遍历找到目标 offset
-
时间戳索引文件
- 如果我们需要使用时间戳来寻找的时候,和 offset 相比只是多加了以及索引,也就是通过二分找到时间戳对应的 offset,再重复之前的步骤找到相应的文件数据
3.4.3 Consumer
Consumer 和 Partition 的分配问题:也就是对于每一个Partition 来讲,该由哪一个 Consumer 来消费的问题,对于这个问题,我们一般有两种解决方法,手动分配和自动分配
-
手动分配(Low Level):
在启动的时候分配任务,哪个 Consumer 负责拉取哪几个 partition,但是万一其中一个 Consumer 宕机,就会导致无法拉取到完全的 partition -
自动分配(High Level):也就是对于每一个消费者组,都会
选择一个 Broker 作为一个协调者 Coordinator,这个协调者负责分配各个消费者获取 partition 的任务,这使得可以动态调整各个 Consumer 的任务
3.5 Kafka 的缺点
- 运维成本高
- 对于负载不均衡场景,解决方案复杂
- 没有自己的缓存,完全依赖 Page Cache
- Controller 和 Coordinator 以及 Broker 在同一进程内,大量 IO 会导致其性能下降
4. 总结
Kafka 一般用于离线业务场景,比如日志信息、Metrics数据和用户行为分析等
参考:
- 字节内部课:走进消息队列