消息队列学习笔记
消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式。消息队列提供了异步的通信协议。本文将基于《走进消息队列》对消息队列进行介绍。
背景
消息队列的出现,主要是由以下几个方面的场景问题催生的:
- 系统崩溃
- 服务处理能力有限
- 链路耗时长尾
- 日志难以处理
而消息队列的出现,恰恰就能很好地解决以上四个场景中的问题。对于系统崩溃问题,消息队列能使系统解耦,防止因为记录存储程序所在的机房被删库跑路而导致系统崩溃;对于服务处理能力有限问题,消息队列可以通过削峰的方式,比如每次只获取10个请求进行处理,这样在面对庞大的请求量时,处理订单的服务压力也能得到缓解;对于链路耗时长尾问题,消息队列可以通过异步的方式,提前将响应返回给用户,最大程度挽留住用户;对于日志难以处理的问题,同样也可以利用消息队列的优势解决。
定义
那么什么是消息队列呢,消息队列(MQ),指保存消息的一个容器,本质是个队列。但这个队列呢,需要支持高吞吐,高并发,并且高可用。
业界消息队列对比
Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计
BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
Kafka消息队列介绍
使用步骤
Kafka的使用步骤如下图所示:
下面对以上一些基本概念进行解释:
逻辑队列(Topic)与分片(Partition)
在 Kafka 中,消息以逻辑队列(Topic) 来分类。同时,为了解决吞吐量不足的问题,Kafka中引入了分片(Partition) 的概念,对逻辑队列进行水平扩展。
生产者与消费者
在Kafka中,客户端有生产者(Producer) 和消费者(Consumer) 两种基本类型。
生产者/发布者创建消息,而消费者/订阅者负责负责消费 Topic 中的消息。
Kafka中还有消费者组(Consumer Group)的概念,不同组 Consumer 消费进度互不干涉
Broker 和物理集群(Cluster)
Broker实质上就是指一个Kafka服务器,可以接收生产者发送的消息,并且存入到磁盘中。此外,Broker还可以拉取分片消息的请求,返回目前已经提交的消息给消费者。
多个 Broker 组成一个集群(Cluster),每个集群中可以建立多个不同的 Topic。
Offset
消息在 partition 内的相对位置信息,可以理解为唯一ID,在 partition 内部严格递增。
Replica
每个分片有多个 Replica,Leader Replica 将会从 ISR 中选出。
数据复制
Kafka存在的问题
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖 Page Cache
- Controller 和 Coordinator和Broker 在同一进程中,大量 IO会造成其性能下降
结语
Kafka中还有很多概念我没有在这里记录,包括Producer的批量发送和数据压缩,Broker的数据存储、消息文件结构、磁盘结构拷贝操作,Consumer的Rebalance等。有兴趣的可以看课程或者查阅官方文档进一步了解。
个人觉得里面的一些概念还是很有意思的,比如一些提高吞吐量或者稳定性的思想都值得我们学习。学习一门技术远远不如学习一种好的思想。在以后的开发过程中,我们也可以思考如何能将这些思想应用到产品的效率、性能和稳定性中(前提当然是保证项目的完整性)。
总之,学习了这次课程中,我不仅学习了新知识,更重要的是学到了消息队列中的设计和优化思想,受益匪浅。