RocketMQ高可用架构涉及常用功能整理
- 1. 集群高可用系统架构和相关组件
- 1.1 架构说明
- 1.2 相关概念说明
- 1.3 消息模型
- 1.3.1 点对点模型
- 1.3.2 发布订阅模型
- 1.3.3 消息过滤
- 2. rocketmq的核心参数
- 3. rocketmq常用命令
- 4. 事务性
- 4.1 数据写入流程
- 4.2 数据读流程
- 4.3 事务消息
- 5. 疑问和思考
- 5.1 rocketmq的数据删除策略是怎样的?
- 6. 参考文档
探讨rocketmq的系统架构以及以及整体常用的命令和系统分析,本文主要探讨高可用版本的rocketmq集群,并基于日常工作中的沉淀进行思考和整理。更多关于分布式系统的架构思考请参考文档关于常见分布式组件高可用设计原理的理解和思考
1. 集群高可用系统架构和相关组件
在常用的3大mq中,各有各自的性能差异,并且也有相互的弊端
- ActiveMQ: 产品比较成熟,产品出现的比较早,能够支持多种客户端语言,相关的sdk相对丰富。但是产品功能相对简单,并且在设计之初是单机版,虽然后续有高可用版本,但是整体上集群的性能和高可用能力整体偏弱 ActiveMQ高可用架构涉及常用功能整理
- RocketMQ: 产品上能够提供高可用能力,能够支持多种客户端语言,相关的sdk相对丰富,能够提供丰富的数据路由模式,并且鉴权设计完善。但是在多种模式中(比如镜像模式),数据使用镜像模式,集群的性能整体能力偏弱 RabbitMQ高可用架构涉及常用功能整理
- Kafka: kafka的数据定位跟MQ略有不同,最大的不同时kafka不能提供消息生产即删除的语义,这会导致在产品定位上略有不同 KAFKA高可用架构涉及常用功能整理
纵观这3大mq的性能特点,似乎缺少一种能够提供强大的高可用扩展能力,并且能够提供丰富的mq特性的产品,并且能够完善的鉴权设计的产品。这也许就是rocketmq这个产品能够生产和问世的出发点。事实上,rocketmq在架构设计上,明显弥补了如上mq所面临的问题。但是由于rocketmq产品问世的时间较短,对java语言能够提供丰富的sdk,但是对于其他开发语言的支持以及社区生态还需要进一步建设。
1.1 架构说明
rocketmq的整体架构如下
相关核心的组件和角色作用如下
组件 | 部署模式 | 组件作用 | 备注 |
---|---|---|---|
producer | 客户端部署 | 生产者创建消息 | 消息一般可以包含 2 个部分: 消息体和标签 |
consumer | 客户端部署 | 消费者连接到 RocketMQ 服务器,订阅到队列。消费者消费一条消息时,只消费消息的消息体(payload) | 在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只有消息体,消费者只会消费到消息体,也就不知道消息的生产者是谁,当然消费者也不需要知道 |
NameServer | 多机部署 | NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现 | 主要包括两个功能:Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。然后Producer和Conumser通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。NameServer通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,Broker仍然可以向其它NameServer同步其路由信息,Producer,Consumer仍然可以动态感知Broker的路由的信息。 |
BrokerServer | 多机部署、主从模式 | Broker主要负责消息的存储、投递和查询以及服务高可用保证 | 包含多个子模块,提供完整的消息生产、消费服务 |
1.2 相关概念说明
列出重要的相关概念,更多概念可以参考 官网
角色说明 | 角色作用 | 备注 |
---|---|---|
topic | Apache RocketMQ 中消息传输和存储的顶层容器,用于标识同一类业务逻辑的消息 | 1.定义数据的分类隔离、2.定义数据的身份和权限,可以基于topic进行多租户的权限隔离设计 |
queue | Apache RocketMQ 中消息存储和传输的实际容器,也是 Apache RocketMQ 消息的最小存储单元 | Apache RocketMQ 的所有主题都是由多个队列组成,以此实现队列数量的水平拆分和队列内部的流式存储,类似kafka的partition |
tag | Tag标签过滤方式是 Apache RocketMQ 提供的基础消息过滤能力,基于生产者为消息设置的Tag标签进行匹配。 | 生产者在发送消息时,设置消息的Tag标签,消费者需指定已有的Tag标签来进行匹配订阅。 |
topic和queue之间的关系如下图(类似kafka中的topic和parition关系)
1.3 消息模型
1.3.1 点对点模型
点对点模型也叫队列模型,具有如下特点:
- 消费匿名:消息上下游沟通的唯一的身份就是队列,下游消费者从队列获取消息无法申明独立身份。
- 一对一通信:基于消费匿名特点,下游消费者即使有多个,但都没有自己独立的身份,因此共享队列中的消息,每一条消息都只会被唯一一个消费者处理。因此点对点模型只能实现一对一通信。
1.3.2 发布订阅模型
发布订阅模型具有如下特点:
- 消费独立:相比队列模型的匿名消费方式,发布订阅模型中消费方都会具备的身份,一般叫做订阅组(订阅关系),不同订阅组之间相互独立不会相互影响。
- 一对多通信:基于独立身份的设计,同一个主题内的消息可以被多个订阅组处理,每个订阅组都可以拿到全量消息。因此发布订阅模型可以实现一对多通信。
发布订阅模式下,rocketmq的topic和queue提供的功能跟kafka的topic和partition关系很类似。
1.3.3 消息过滤
消费者订阅了某个主题后,Apache RocketMQ 会将该主题中的所有消息投递给消费者。若消费者只需要关注部分消息,可通过设置过滤条件在 Apache RocketMQ 服务端进行过滤,只获取到需要关注的消息子集,避免接收到大量无效的消息。本文介绍消息过滤的定义、原理、分类及不同过滤方式的使用方法、配置示例等。
Tag标签过滤
Tag标签过滤方式是 Apache RocketMQ 提供的基础消息过滤能力,基于生产者为消息设置的Tag标签进行匹配。生产者在发送消息时,设置消息的Tag标签,消费者需指定已有的Tag标签来进行匹配订阅。
2. rocketmq的核心参数
参考 Admin Tool
3. rocketmq常用命令
参考 Admin Tool
4. 事务性
4.1 数据写入流程
参考 生产者(Producer)
4.2 数据读流程
参考 消费者分组(ConsumerGroup)
4.3 事务消息
事务消息是 Apache RocketMQ 提供的一种高级消息类型,支持在分布式场景下保障消息生产和本地事务的最终一致性。
事务消息交互流程如下图所示。
- 生产者将消息发送至Apache RocketMQ服务端。
- Apache RocketMQ服务端将消息持久化成功之后,向生产者返回Ack确认消息已经发送成功,此时消息被标记为"暂不能投递",这种状态下的消息即为半事务消息。
- 生产者开始执行本地事务逻辑。
- 生产者根据本地事务执行结果向服务端提交二次确认结果(Commit或是Rollback),服务端收到确认结果后处理逻辑如下:
- 二次确认结果为Commit:服务端将半事务消息标记为可投递,并投递给消费者。
- 二次确认结果为Rollback:服务端将回滚事务,不会将半事务消息投递给消费者。
- 在断网或者是生产者应用重启的特殊情况下,若服务端未收到发送者提交的二次确认结果,或服务端收到的二次确认结果为Unknown未知状态,经过固定时间后,服务端将对消息生产者即生产者集群中任一生产者实例发起消息回查。 说明 服务端回查的间隔时间和最大回查次数,请参见参数限制。
- 生产者收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
- 生产者根据检查到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤4对半事务消息进行处理。
更详细环节参考 事务消息
5. 疑问和思考
5.1 rocketmq的数据删除策略是怎样的?
参考 消息存储和清理机制
6. 参考文档
- RocketMQ官网