这是我参与【第五届青训营】伴学笔记创作活动的第十五天。今天学习了消息队列,就写一下消息队列的应用及三种常用消息队列的原理与用途。
消息队列
消息队列(MQ),指保存消息的一个容器,本质是个队列。但这个队列,需要支持高吞吐,高并发,并且高可用。
消息队列引入
面临的问题
- 系统崩溃
- 服务处理能力有限
- 链路耗时长尾
- 日志如何处理
解决方案
引入消息队列。
-
解耦 (防止数据库异常崩溃造成问题)
-
削峰 (提高大量级服务处理能力)
-
异步 (解决链路耗时长尾)
-
日志处理 (平台对日志进行分析)
业界消息队列对比
消息队列—Kafka
适用场景
- 搜索服务
- 直播服务
- 订单服务
- 支付服务
使用方法
- 创建集群
- 新增 Topic(业务场景|逻辑队列)
- 编写生产者逻辑
- 编写消费者逻辑
基本概念和架构
- Topic:逻辑队列,不同的业务场景有不同的 Topic
- Cluster:物理集群,每个集群可以建立多个不同的 Topic
- Productor:生产者,负责将消息发送到 Topic 中
- Consumer:消费者,负责消费 Topic 中的信息
- ConsumerGroup:消费者组,不同组的进度互不干扰
- Partition:分区,不同分区的消息可以并发处理
- Offset:消息在 Partition 内的相对位置信息,可以理解为唯一的 ID,在 Partition 内唯一递增。
- Replica—Leader:对外进行写入和读取
- Replica—Follower:不断拉取 Leader 的信息,努力保持同步,若 Leader出问题,则可替代;若与 Leader 差距过大,则踢出 ISR
- Broker:服务器,将 Topic 的不同 Partition 分布在不同服务器上,由 Controller 控制
- ZooKeeper:负责存储集群元信息,包括分区分配信息等,和 Controller 配合
高性能操作
Productor
Kafka 重点在与高性能大数据,解决网络带宽不够等问题。
- 批量发送:减少IO次数,从而增强发送能力
- 数据压缩:通过压缩,减少消息大小,目前支持 Snappy,Gzip,Lz4, ZSTD等压缩算法
消息存储
- 写消息:采用循序写,提高写速率,采用稀疏索引
- 查消息:二分找到小于目标 offset 的最大文件
数据拷贝—零拷贝
Consumer—Rebalance
问题总结
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖 Page Cache
- Controller 和 Coordinator 和 Broker 在同一进程中,大量IO会造成其性能下降
消息队列—BMQ
兼容 Kafka 协议,存算分离,支持云原生的消息队列。
基础概念
- Proxy Cluster:代理集群
- Broker Cluster:服务器集群
- Meta Storage System:元存储系统
- Distributed Storage System:分布式存储系统
运维操作对比
文件结构
写操作:随机选择一定数量的 DataNode 写入,若故障可换掉部分,保证高可用
高级特性
Proxy
采用代理,使不至于访问过于频繁,同时加快命中,提高读写效率
泳道消息
- 泳道消息开发流程:开发->线下机房环境->产品预览环境->部署
- 泳道 Topic:下游不同泳道消费者只能消费其泳道的消息
Databus
- 简化消息队列客户端复杂度
- 解耦业务与 Topic
- 缓解集群压力,提高吞吐
Mirror
使用Mirror通过最终—致的方式,解决跨Region读写问题。
Index
直接在 BMQ 中将数据结构化,配置索引DDL,通过 Index Query 服务独处数据。可以不单纯靠时间戳和offset 索引查询,能多维度查询,不需要引入外部存储系统
Parquest
Apache Parquet是 Hadoop 生态圈中一种新型列式存储格式,它可以兼容 Hadoop 生态圈中大多数计算框架(Hadoop、Spark等),被多种查询引擎支持(Hive、lmpala、Drill等)
消息队列—RocketMQ
基本概念
架构
存储模型
高级特性
事务场景
通过事务保证实现一致性。
事务消息:消息同事务一样能提交,确认,重传,回滚
延迟发送:分出目标 Topic和 Schedule Topic(延迟服务)