青训营 X 消息队列
最简单的问题:什么是消息队列?
消息队列,指保存消息的一个容器,本质上是一个队列。要求支持高吞吐、高并发、高可用。
Kafka
Kafka是一个分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥出色。搜索服务、直播服务、订单服务和支付服务都是它的使用场景。
使用Kafka的流程可以大致分为四步:
- 创建集群
- 新增Topic
- 编写生产者逻辑
- 编写消费者逻辑
下图为一个Kafka集群(Cluster)的示意图:
Topic是逻辑队列,一个集群中可以存在功能不同的多个Topic;生产者(Producer)负责将消息发送到Topic中;消费者(Consumer)负责消费Topic中的消息;ConsumerGroup是消费者组,不同的消费者的进度互不干扰。
一个Topic内部会有不同的Partition,不同的Partition存储不同的消息队列,通过offset可以获取消息在Partition内的相对位置(offset在一个Partition内严格递增)。每个Partition中会有多个Replica来保证可用性,其中会分为Leader和Follower两种进行主从复制。
生产者向Broker发送消息,Broker收到后会返回给消费者一个Success通知。Broker采用顺序写将消息写入到本地磁盘。消费者向Broker发送FetchRequest请求消息数据,Broker会将指定的offset处的消息按照时间窗口和消息大小窗口发送给消费者。在查找消息时,Broker通过二分查找,找到小于目标offset的最大索引位置。
Kafka在实际使用中面临一些问题:
- 运维成本高
- 负载均衡解决复杂
- 缺少自身的缓存,依赖于Page Cache
- Controller和Coordinator和Broker在同一进程中,大量IO会造成其性能下降
BMQ
相较Kafka增加了Proxy层,并且使Controller和Coordinator独立于Broker。在写文件时,会随机选取一定数量的DataNode来存储副本。通过各种机制提供了容灾和冗余备份,并降低了运维的复杂度。目前网络上能查到的资料比较少,入门学习可能有些困难。
RocketMQ
更倾向低延时场景,比如电商业务线与业务峰值时刻等。
引入了NameServer的概念,为消费者和生产者提供了路由功能,帮助其找到合适的Broker。RocketMQ将主从复制的层级提高到了Broker层级,因此副本决策和Kafka有很大区别。
RocketMQ还提供一些高级特性:
- 提供了事务功能,保证事务执行的原子性。
- 提供延迟队列,以延迟处理某些消息。
- 提供重试和死信队列,以处理消息消费过程中的异常。
小结
消息队列是开发中非常重要的一环,对于处理业务不可缺少,但对在校生而言,日常开发中可能接触较少,相对薄弱,因此可能需要进行针对性的学习,以贴近业界需求。
坚持学习,无限进步!