这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
本篇笔记主要记录一下消息队列的学习知识
1.什么是消息队列?
2.Kafka
- Topic:逻辑队列,不同Topic可以建立不同的Topic
- Cluster:物理集群,每个集群中可以建立多个不同的Topic
- Producer:生产者,负责将业务消息发送到Topic中
- Consumer:消费者,负责消费Topic中的消息
- ConsumerGroup:消费者组,不同组Consumer消费进度互不干涉
Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增
Topic内部:
每个分片有多个Replica,Leader Replica将会从ISR中选出
Partition内部:
数据复制:
- Broker:Kafka集群中的节点,包含了2个Topic,其中有一个Broker充当Controller的作用,相当于主节点,能够进行分配
架构:
1.一条消息的自述
2.Producer
- 批量发送:减少IO次数从而加强发送效率
- 数据压缩:当消息太大的情况下,通过压缩减少消息大小,目前支持Snappy、Gzip、LZ4、ZSTD压缩算法
3.Broker
- 数据存储:
通过日志进行写入到磁盘中。由于磁盘结构,写入方式为顺序写,以提高写入效率
- 寻找消息:Consumer通过发送FetchRequest请求消息数据,Broker会将指定Offset处的消息,按照时间窗口和消息大小窗口发送给Consumer。其中的寻找Offset方式为二分查找到小于目标Offset的最大文件,也有寻找时间戳方式,也是二分查找到小于目标时间戳的最大索引位置,然后再通过寻找Offset的方式寻找到最终数据
- 零拷贝:与传统拷贝方式不同,Kafka通过系统调用中的send file方式,从而达到将数据从磁盘读到内核空间中通过网卡发送到应用空间
4.Consumer
分配partition到ConsumerGroup的方式:
- 手动:手动进行分配,哪个Consumer消费哪一个Partition完全由业务决定,但是无法自动容灾,新增Consumer需要重新启停
- 自动:在Broker集群中,通过选取一台Broker充当Coordinator,Coordinator可以实现自动分配 (Rebalance方式)
5.缺点
- 数据复制问题:通过复制副本达到集群中数据的一致,但是如果Leader Broker被关闭,集群中会重选Leader,但是这个过程中数据依旧在写入导致数据不一致
- 替换、扩容、缩容:与上面提到的重启类似
- 负载不均衡:为了降低负载,可能会迁移高负载的partition,但是这样依旧会提高IO
3.BMQ
兼容Kafka协议,存算分离,云原生消息队列
对于Kafka的缺点进行的修改比较:
1.文件写入
随机选择一定数量的DataNode进行写入
2.Broker
- 状态机: 保证对于任意分片在同一时刻只能在一个Broker上存活
- 写文件流程:
FailOver机制处理写入异常
3.Proxy
Wait机制: 避免请求频繁,从而降低压力
4.高级特性
- 泳道消息:解决主干泳道流量隔离问题以及泳道资源重复创建问题
- DataBus:
简化消息队列客户端负责度;解耦业务和Topic;缓解集群压力,提高吞吐
- Mirror:为了解决跨region读写问题
- Index:直接在BMQ中将数据结构化,配置索引DDL,异步构建索引后,通过Index Query服务读取数据
- Parquet:一种列式存储格式
4.RocketMQ
架构:
高级特性:
- 事务消息:
在发送消息之后会在本地执行事务逻辑,然后告诉Server这个事务是需要Commit还是rollback,如果没有等到Server的回复,那么会在本地事务中检查,根据本地事务的结果重发告诉Server需要Commit还是rollback
- 延迟消息:
生产的消息会先发送到CommitLog,如果是延迟消息,会再发送给ScheduleTopic中,在这个队列中会有一个开源的异步线程消费延迟消息,在到达时间后会回写到CommitLog中,此时目标Topic才可以进行消费这条延迟消息
- 消费重试和死信队列:
人生苦短,不如go浪一下。