什么是消息队列
MessageQueue,指保存消息的一个容器,本质是个队列,但支持高吞吐、高并发、高可用。作为一个单独的中间件产品存在,独立部署。
大概为:系统A--写消息-->MQ--读消息-->系统B
使用消息队列的理由
- 解耦:降低耦合度
- 异步:执行任务时无需等待当前任务的完成也可以同时进行其他任务。(和并发是不同的概念)
- 削峰:将某一段时间的超高流量分摊到更长的一段时间内去消化,避免了流量洪峰击垮系统。
常见消息队列
- Kafka: 分布式、分区、多副本的日志提交服务,适用高吞吐
- RocketMQ: 低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,适用实时场景
- Pulsar: 下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体、采用存算分离的架构设计
- BMQ: 和Pulsar架构类似,初期定位事承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
Kafka
运用场景:
- 搜索服务
- 直播服务
- 订单服务
- 支付服务
使用Kafka
基本概念
使用步骤
- 1.创建集群(Cluster)
- 2.新增Topic:在集群中创建一个Topic(Kafka中的逻辑队列,可以理解为每一个不同业务场景就是一个Topic,且对于该业务,所有数据都储存在这个Topic中),并设置好分片(Partition)数量
- 3.编写生产者(Producer)逻辑:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个生产者,调用Send方法,发送消息
- 4.编写消费者(Consumer)逻辑:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个消费者,调用Poll方法,接收消息
- 在集群的基础上还有一个ZooKeeper模块,该模块存储了集群的元数据信息(比如副本的分配信息、Controller计算好的方案)
通常Topic会有多个分片,不同分片直接消息是可以并发处理的,以提高单个Topic的吞吐 生产者:向主题发布消息的客户端应用程序称为生产者(Producer),生产者用于持续不断的向某个主题发送消息。
消费者:订阅主题消息的客户端程序称为消费者(Consumer),消费者用于处理生产者产生的消息。
消费者群组:生产者与消费者的关系就如同餐厅中的厨师和顾客之间的关系一样,一个厨师对应多个顾客,也就是一个生产者对应多个消费者,消费者群组(Consumer Group)指的就是由一个或多个消费者组成的群体。
架构
一个典型的 Kafka 集群中包含
- 若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等)
- 若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高)
- 若干Consumer Group
- 一个Zookeeper集群。
Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。
对于每一个分片来说,每一条消息都有唯一的一个Offset来作为消息在分片内的相对位置信息
而分片的副本Replica分布在不同的机器上以容灾
在下图中,Leader对外服务,Follower异步拉取Leader的数据进行一个同步,如果Leader挂了,可以将Follower提升为Leader再对外进行服务
图中Broker代表每一个Kafka节点(独立的Kafka服务器,接收来自Producer的消息并为其设置偏移量,提交消息到磁盘保存);
所有的Broker节点最终组成一个集群(本图包含4个节点);
图中集群有两个Topic,Topic1有2个分片,Topic2有1个分片,无论Topic1还是Topic2,分片都有三个副本;
Controller是整个集群的大脑,负责对副本和Broker进行分配。
优缺点
优点:
- 高吞吐、低延迟:kakfa收发消息非常快,它的最低延迟只有几毫秒;
- 高伸缩性:每个topic 包含多个partition,topic中的partition可以分布在不同的broker中;
- 持久性、可靠性:Kafka 能够允许数据的持久化存储,消息被持久化到磁盘,并支持数据备份防止数据丢失,Kafka 底层的数据存储是基于 Zookeeper 存储的,Zookeeper 的数据能够持久存储;
- 容错性高:kafka是分布式的,一个数据多个副本,某个节点宕机,Kafka 集群能够正常工作;
缺点:
- Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长;
- 使用短轮询方式,实时性取决于轮询间隔时间;
- 消费失败不支持重试;
- 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
- 社区更新较慢。