这是我在青训营笔记传作活动中的第7篇
消息队列
本次课程从消息队列的应用场景、发展历史入手,引出了常见的消息队列类型,介绍了现在流行的三大消息队列:Kafka、BMQ、RocketMQ。
在 Kafka 部分,围绕使用场景,业务日志、用户行为数据、Metrics 数据展开,介绍一条消息从生产到消费的处理流程,最后基于 Kafka 在使用中遇到的问题引出了 BMQ 架构,讲解 BMQ 各模块在实际应用中如何工作以及 BMQ 多机房容灾相关知识点;最后对阿里的 RocketMQ 产品进行了对比介绍 ...
消息队列的前世今生
消息队列(MQ),指保存消息的一个容器,本质是个队列。要想称之为消息队列,这个队列要支持 高吞吐、高并发 并且 高可用。
- 应用场景
消息队列的使用场景有很多,常见的有:解耦、削峰、异步、日志处理。- 应用解耦
在传统架构中,各个模块之间需要相互调用,共享数据,每个模块都要关注其他模块是否更改了数据,是否正常运行等等,模块之间的耦合度很高。引入消息队列以后,将共享数据放入消息队列,各个模块对该数据感兴趣只需要订阅即可,模块的业务逻辑也相对独立,可以很大程度上避免模块间的调用,提高了系统的可扩展性。 - 异步处理
在用户发起请求后,系统会调用下游接口,等待接口全部返回后才可以通知用户。如果下游接口返回的数据对于用户来说不是必要的,那么可以在用户发送请求后,把数据传给消息队列,然后直接告诉用户已经发送了信息,之后再把消息队列的数据发送到下游接口。 - 流量削峰
平常用户的请求会直接访问数据库,数据库的承压能力是有限的,如果访问量很大的时候,比如秒杀常见,很可能因为流量暴增导致整个业务挂掉,引入消息队列以后可以把请求存入消息队列,然后再慢慢处理。 - 日志处理
- 应用解耦
消息队列----Kafka
kafka 往往用于离线消息处理,类似服务器的日志信息反馈,分析,处理。同时也适用于处理程序运行的 Metrics 数据以及一些用户行为,如用户的搜索,点赞,评论,收藏。
-
Kafka的使用
- 首先需要创建一个 Kafka 集群;
- 在这个集群中创建一个 Topic,并且设置好分片数量;
- 编写生产者逻辑,引入对应语言的 SDK,配置好集群和 Topic 等参数,初始化一个生产者,调用 Send 方法发送消息;
- 编写消费者逻辑,引入对应语言的 SDK,配置好集群和 Topic 等参数,初始化一个消费者,调用 Poll 方法接收消息。
-
基本架构
- Topic:逻辑队列,一个 Topic 中拥有多个分区(Partition),分区是可以并发处理的。
- Cluster:物理集群,每个集群中可以建立多个不同的 Topic。
- Producer:生产者,负责将业务消息发送到 Topic 中。
- Consumer:消费者,负责消费 Topic 中的消息。
- ConsumerGroup:消费者组,包含多个消费者,每个消费者的消费进度互不干涉。
这其中还涉及到 Topic 内的 offset(相对位置),Replica(副本),以及副本分布相关概念
- Partition:通常 Topic 会有多个分片,不同分片之间消息是可以并发来处理的,这样提高单个 Topic 的吞吐量。
- Offset:消息在 Partition 内的相对位置信息,可以理解为唯一 ID,在 Partition 内部严格递增。
- Replica:Partition 的副本,可用来容灾,这些副本有着不同的角色,分别是 Leader 和 Follower,Leader 对外服务,Follower 异步去拉取 Leader 的数据进行一个同步,如果 Leader 挂掉了,可以将 Follower 提升成 Leader 再对外进行服务。
- ISR:同步中的副本,对于 Follower 来说,始终和 Leader 是有一定差距的,但当这个差距比较小的时候,我们就可以将这个 Follower 副本加入到 ISR 中,不在 ISR 中的副本是不允许提升成 Leader 的。
在集群的基础上,还有一个模块是 ZooKeeper,这个模块其实是存储了集群的元数据信息,比如副本的分配信息等等,Controller 计算好的方案都会放到这个地方。
-
Kafka 的缺点 kafka 的升级,替换,扩缩容流程很繁琐,由于 kafka 只能单台重启,同时重启后还要经历数据同步与 leader 回调的步骤,因此在执行升级和扩缩容时会产生很大的时间开销,同时由于 kafka 缺少负载均衡与缓存手段,因此 kafka 面临负载不均衡的问题以及依赖外部 Cache。
消息队列----BMQ
BMQ 是字节跳动出品的消息队列产品,解决了 Kafka 在实际应用中的诸多问题。
- BMQ 读写流程 在 BMQ 中,客户端写入前会选择一定数量的 DataNode,这个数量一般是副本数,然后将一个文件写入到这几个节点上,切换到下一个 segment 之后,又会重新选择节点进行写入。这样对于单个副本的所有 segment,会随机写入到集群当中。 对于写入逻辑,BMQ 还有一个状态机的机制(Broker-Partition),用来保证不会出现同一个分片在两个 Broker 上同时启动的情况,另外也能保证一个分片的正常运行。
消息队列---RocketMQ
RocketMQ 是阿里出品的消息队列,针对电商业务线,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等。