消息队列 | 青训营

98 阅读4分钟

消息队列基本概念

消息队列概述

一个使用队列来通信的组件,生产者把发送的消息存在队列中,消费者在队列中取得该消息。本质是转发器。

使用场景

1、应用耦合:即多个应用通过MQ对同一消息进行处理,避免调用接口失败而导致整个过程失败, 2、异步处理。 3、限流削峰:常用于电商活动,避免流量过大导致系统崩溃。 4、消息驱动的系统

Kafka

Kafka是一个分布式,具有高吞吐量和高扩展性的消息队列系统。

基本模型

image.png

image.png

Topic主题

每一个发送到Kafka的消息都有一个主题,也可叫做一个类别。例如发送一个主题为order的消息,则该order类别下就会有多条订单的消息。

partition分区

生产者发送的消息数据Topic会被存储在分区中,合理的把消息分布在不同的分区上,而分区是被分在不同的Broker上也就是服务器上,这样大量的消息就实现了负载均衡。一个Topic可以指定多个分区,但是至少指定一个分区。每个分区存储的数据都是有序的,不同分区间的数据不保证有序性。那么当需要保证消息的顺序消费时,可以单独设置一个分区,使消费者只能消费这一个分区,自然就保证有序。

如何选择partition

1、生产者写入时如果有指定的分区则写入该分区 2、没有指定分区,但是设置了数据的key,则计算其hash值找到一个分区。 3、若既没有制定分区也没有设置key,则轮询出一个分区。

partition结构

Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。 文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。

Replica副本

即分区中数据的备份,是为了防止数据丢失或者服务器宕机而采取的保护数据完整性的措施。Kafka会找一个分区作为主分区(leader)来控制消息的读写,其他的(副本)都是从分区(follower),读写通过leader来控制,然后同步到副本上去,保证的数据的完整性。如果有某些服务器宕机,我们可以通过副本恢复数据,也可以暂时用副本中的数据来使用。

broker节点或实例

启动一个kafaka就是一个broker,多个broker构成kafka集群,体现了分布式的思想。

Message结构

由offset、消息大小、消息体组成。 offset为一个字节的有序id,用来唯一确定每条消息在partition内的位置。

kafka高性能原因

1、磁盘顺序读写 2、数据传输通过mmap和transfile实现零拷贝 3、读写数据批量处理与压缩传

kafka存在哪些问题

1、运维成本高 2、对于负载不均衡的场景,解决方案复杂 3、没有自己的缓存,完全依赖page chche 4、controller、coordinator和broker在同一个进程中,大量IO造成性能下降

BMQ

兼容了kafka协议,存算分离,是云原生消息队列,解决了kafka的一些弊端

image.png

如何解决kafka负载不均衡问题

写入文件时,kafka是先在leader上写好文件,之后同步到follower,对于同一个副本的所有segment都在同一台机器,因此会有由于单分片过大而导致的负载不均衡的问题。BMQ集群中,对于单个副本而言,是随机分配到不同节点的,因此不存在负载不均。

RocketMQ

主要针对电商业务,和其他许多业务峰值时刻。

image.png

存储模型

image.png

对于一个broker来说,所有消息都会append到一个commitlog上面,再根据不同的queue,重新分派到不同的consumer,consumer就可以按照queue进行拉取消费。但是这里的consumerqueue存储的不是真实的数据,真实数据在commitlog中,因此所存的知识这个queue所有消息在commitlog上的位置,相当于数是这个queue的一个密集索引。

高级特性

1、事务消息 2、延迟队列 3、消费重试和死信队列 image.png