这是我参与「第五届青训营」伴学笔记创作活动的第 8 天,本文主要介绍了消息队列的底层原理、架构设计。
问题提出
- 系统崩溃
- 服务处理能力有限
- 链路耗时长尾
- 日志如何处理
解决方案
- 解耦
- 削峰
- 异步
- 消息队列(指保存消息的一个容器,本质是个队列。但这个队列呢,需要支持高吞吐、高并发、并且高可用。)
消息队列
- Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
如何使用Kafka
- 创建一个Kafka集群
- 在这个集群中创建一个Topic,并且设置好分片数量
- 引入对应语言的SDK,配置好集群和Topic等参数,初始化一个生产者,调用Send方法,将你的Hello World发送出去
- 引入对应语言的SDK,配置好集群和Topic等参数,初始化一个消费者,调用Poll方法,你将收到你刚刚发送的Hello World
基本概念
- Topic:逻辑队列,不同Topic可以建立不同的Topic
- Cluster:物理集群,每个集群中可以建立多个不同的Topic
- Producer:生产者,负责将业务消息发送到Topic中
- Consumer:消费者,负责消费Topic中的消息
- ConsumerGroup:消费者组,不同组Consumer消费进度互不干涉
Offset
消息在partition内的相对位置消息,可以理解为唯一ID,在partition内部严格递增
Replica
每个分片有多个Replica,Leader Replica将会从ISR中选出
数据复制
Producer
- 批量发送:批量发送可以减少IO次数,从而加强发送能力
- 数据压缩:通过压缩,减少消息大小,目前支持Snappy、Gzip、LZ4、ZSTD压缩算法
Broker
- 数据的存储
- 消息文件结构
- 磁盘结构:移动磁头找到对应磁道,磁盘转动,找到对应扇区,最后写入。寻道成本比较高,因此顺序可以减少寻道所带来的时间成本
- 顺序写:采用顺序写的方式进行写入,以提高写入效率
- 找到消息:Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer
- 寻找数据:偏移量索引文件、时间戳索引文件、传统数据拷贝、零拷贝、消息的接收端、Low Level、High Level、Consumer Rebalance
Kafka提高吞吐或稳定性的问题
- 数据复制问题
- 重启操作
- 替换、扩容、缩容
- 负载不均衡