这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
消息队列
一、什么是消息队列
消息队列,指保存消息的一个容器,本质是个队列。但是这个队列需要支持高吞吐、高并发、高可用
消息队列的使用场景
-
系统奔溃:业务中的某个部分的服务器被删库跑路,导致调用接口失败
应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败
-
服务处理能力有限:数据量超越服务器所能承载的最大量
限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况
-
链路耗时长尾:业务流程过于冗长,导致服务器处理时间过长
异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间
-
日志如何处理
利用消息队列处理日志
二、kafka
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据
kafka的设计目标
- 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能
- 高吞吐率,即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输
- 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输
- 同时支持离线数据处理和实时数据处理
kafka的架构
- Producer :消息生产者,就是向kafka broker发消息的客户端
- Consumer :消息消费者,向kafka broker取消息的客户端
-
Topic :kafka中的逻辑队列,可以理解成每一个不同的业务场景就是一个不同的topic,对于这个业务来说,所有的数据都存储在该队列中
-
Cluster:kafka的物理集群,每个集群可以建立多个不同的topic
-
Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic
-
Partition:topic的分片,不同分片的直接消息可以通过并发来处理
-
Consumer Group (CG):一个topic可以有多个CG,不同CG的消费者互不干涉
-
Offset:kafka的存储文件都是按照offset.kafka来命名
-
Controller:集群大脑,负责对副本和Broker进行分配
-
ZooKeeper:存储集群的元数据信息
-
Replica:分片的副本,分布在不同的机器上,可以用来容灾,leader对外服务,follower异步去拉去leader的数据进行一个同步,如果leader挂了,可以将follower提升为leader再对外服务
kafka的数据传输
数据一条一条的传输,当数据量足够大时,会造成相应时间过长,IO消耗也非常巨大,通过打包可以减少IO消耗,但会造成数据巨大,所以传输的是打包后压缩好的数据,这样就能承受海量数据的传输
Broker如何找到消息
文件的存储采用的是稀疏索引的方式
偏移量索引查找
利用二分查找找到offset小于目标文件的最大索引位置,再顺序查找
时间戳索引查找
二分查找找到对应的时间戳,再用偏移量索引的方式查找
Consumer消息接收
LOW-LEVEL
手动分配,启动比较快,但如果某个消费者挂了或需要新增消费者,需要停掉整个集群,重新分配后再上线
HIGH-LEVEL
选取一个broker作为coordinator,帮助CG进行分配,这样,无论是有消费者宕机还是新增消费者,coordinator都能重新分配CG和partition
kafka问题总结
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存
- controller、coordinator和broker在同一进程中,大量IO会导致性能下降
三、BMQ
兼容kafka协议,存算分离,云原生消息队列
BMQ架构
与kafka的运维操作对比
BMQ和kafka相比,性能的提升是显著的
BMQ文件结构
在BMQ集群中,单个副本是随机分配到不同的结点上面的,所以不会出现负载不均衡的问题
BMQ高级特性
泳道消息:
DataBus:
- 简化消息队列客户端复杂度
- 解耦业务与Topic
- 缓解集群压力,提高吞吐
Mirror:
Index:直接在BMQ中将数据结构化,配置索引DDL,异步构建索引后,通过Index Query服务读出数据
Parquet:直接在BMQ中将数据结构化,通过Parquet Engine,可以使用不同的方式构建Parquet文件
BMQ的读写流程
-
Failover
-
状态机
四、RocketMQ
RocketMQ架构
与kafka的比较
RocketMQ高级特性
-
事务消息
-
消费重试和死信队列
-
延迟队列