共计 6195 个字符,预计需要花费 16 分钟才能阅读完成。
本文转载自 阿里中间件团队博客的文章十分钟入门 RocketMQ
本文首先引出消息中间件通常须要解决哪些问题,在解决这些问题当中会遇到什么艰难,Apache RocketMQ 作为阿里开源的一款高性能、高吞吐量的分布式消息中间件否能够解决,标准中如何定义这些问题。而后本文将介绍 RocketMQ 的架构设计,以期让读者疾速理解 RocketMQ。
消息中间件须要解决哪些问题?
Publish/Subscribe
公布订阅是消息中间件的最基本功能,也是绝对于传统 RPC 通信而言。在此不再详述。
Message Priority
标准中形容的优先级是指在一个音讯队列中,每条音讯都有不同的优先级,个别用整数来形容,优先级高的音讯先投递,如果音讯齐全在一个内存队列中,那么在投递前能够依照优先级排序,令优先级高的先投递。
因为 RocketMQ 所有音讯都是长久化的,所以如果依照优先级来排序,开销会十分大,因而 RocketMQ 没有特意反对音讯优先级,然而能够通过变通的形式实现相似性能,即独自配置一个优先级高的队列,和一个一般优先级的队列,将不同优先级发送到不同队列即可。
对于优先级问题,能够演绎为 2 类:
- 只有达到优先级目标即可,不是严格意义上的优先级,通常将优先级划分为高、中、低,或者再多几个级别。每个优先级能够用不同的 topic 示意,发消息时,指定不同的 topic 来示意优先级,这种形式能够解决绝大部分的优先级问题,然而对业务的优先级精确性做了斗争。
- 严格的优先级,优先级用整数示意,例如 0 ~ 65535,这种优先级问题个别应用不同 topic 解决就十分不适合。如果要让 MQ 解决此问题,会对 MQ 的性能造成十分大的影响。这里要确保一点,业务上是否的确须要这种严格的优先级,如果将优先级压缩成几个,对业务的影响有多大?
Message Order
音讯有序指的是一类音讯生产时,能依照发送的程序来生产。例如:一个订单产生了 3 条音讯,别离是订单创立,订单付款,订单实现。生产时,要依照这个程序生产能力有意义。然而同时订单之间是能够并行生产的。
RocketMQ 能够严格的保障音讯有序。
Message Filter
Broker 端音讯过滤
在 Broker 中,依照 Consumer 的要求做过滤,长处是缩小了对于 Consumer 无用音讯的网络传输。
毛病是减少了 Broker 的累赘,实现绝对简单。
- 淘宝 Notify 反对多种过滤形式,蕴含间接依照音讯类型过滤,灵便的语法表达式过滤,简直能够满足最刻薄的过滤需要。
- 淘宝 RocketMQ 反对依照简略的 Message Tag 过滤,也反对依照 Message Header、body 进行过滤。
- CORBA Notification 标准中也反对灵便的语法表达式过滤。
Consumer 端音讯过滤
这种过滤形式可由利用齐全自定义实现,然而毛病是很多无用的音讯要传输到 Consumer 端。
Message Persistence
消息中间件通常采纳的几种长久化形式:
- 长久化到数据库,例如 Mysql。
- 长久化到 KV 存储,例如 levelDB、伯克利 DB 等 KV 存储系统。
- 文件记录模式长久化,例如 Kafka,RocketMQ
- 对内存数据做一个长久化镜像,例如 beanstalkd,VisiNotify
- (1)、(2)、(3) 三种长久化形式都具备将内存队列 Buffer 进行扩大的能力,(4) 只是一个内存的镜像,作用是当 Broker 挂掉重启后依然能将之前内存的数据恢复进去。
JMS 与 CORBA Notification 标准没有明确阐明如何长久化,然而长久化局部的性能间接决定了整个消息中间件的性能。
RocketMQ 充分利用 Linux 文件系统内存 cache 来进步性能。
Message Reliablity
影响音讯可靠性的几种状况:
- Broker 失常敞开
- Broker 异样 Crash
- OS Crash
- 机器掉电,然而能立刻复原供电状况。
- 机器无奈开机(可能是 cpu、主板、内存等关键设备损坏)
- 磁盘设施损坏。
(1)、(2)、(3)、(4) 四种状况都属于硬件资源可立刻复原状况,RocketMQ 在这四种状况下能保障音讯不丢,或者失落大量数据(依赖刷盘形式是同步还是异步)。
(5)、(6) 属于单点故障,且无奈复原,一旦产生,在此单点上的音讯全副失落。RocketMQ 在这两种状况下,通过异步复制,可保障 99% 的音讯不丢,然而依然会有极少量的音讯可能失落。通过同步双写技术能够完全避免单点,同步双写势必会影响性能,适宜对音讯可靠性要求极高的场合,例如与 Money 相干的利用。
RocketMQ 从 3.0 版本开始反对同步双写。
Low Latency Messaging
在音讯不沉积状况下,音讯达到 Broker 后,能立即达到 Consumer。
RocketMQ 应用长轮询 Pull 形式,可保障音讯十分实时,音讯实时性不低于 Push。
At least Once
是指每个音讯必须投递一次。
RocketMQ Consumer 先 pull 音讯到本地,生产实现后,才向服务器返回 ack,如果没有生产肯定不会 ack 音讯,所以 RocketMQ 能够很好的反对此个性。
Exactly Only Once
- 发送音讯阶段,不容许发送反复的音讯。
- 生产音讯阶段,不容许生产反复的音讯。
只有以上两个条件都满足状况下,能力认为音讯是“Exactly Only Once”,而要实现以上两点,在分布式系统环境下,不可避免要产生微小的开销。所以 RocketMQ 为了谋求高性能,并不保障此个性,要求在业务上进行去重,也就是说生产音讯要做到幂等性。RocketMQ 尽管不能严格保障不反复,然而失常状况下很少会呈现反复发送、生产状况,只有网络异样,Consumer 启停等异常情况下会呈现音讯反复。
Broker 的 Buffer 满了怎么办?
Broker 的 Buffer 通常指的是 Broker 中一个队列的内存 Buffer 大小,这类 Buffer 通常大小无限,如果 Buffer 满了当前怎么办?
上面是 CORBA Notification 标准中解决形式:
- RejectNewEvents 回绝新来的音讯,向 Producer 返回 RejectNewEvents 错误码。
依照特定策略抛弃已有音讯
- AnyOrder – Any event may be discarded on overflow. This is the default setting for this property.
- FifoOrder – The first event received will be the first discarded.
- LifoOrder – The last event received will be the first discarded.
- PriorityOrder – Events should be discarded in priority order, such that lower priority events will be discarded before higher priority events.
- DeadlineOrder – Events should be discarded in the order of shortest expiry deadline first.
RocketMQ 没有内存 Buffer 概念,RocketMQ 的队列都是长久化磁盘,数据定期革除。
对于此问题的解决思路,RocketMQ 同其余 MQ 有十分显著的区别,RocketMQ 的内存 Buffer 形象成一个有限长度的队列,不论有多少数据进来都能装得下,这个有限是有前提的,Broker 会定期删除过期的数据,例如 Broker 只保留 3 天的音讯,那么这个 Buffer 尽管长度有限,然而 3 天前的数据会被从队尾删除。
此问题的实质起因是网络调用存在不确定性,即既不胜利也不失败的第三种状态,所以才产生了音讯重复性问题。
回溯生产
回溯生产是指 Consumer 曾经生产胜利的音讯,因为业务上需要须要从新生产,要反对此性能,Broker 在向 Consumer 投递胜利音讯后,音讯依然须要保留。并且从新生产个别是依照工夫维度,例如因为 Consumer 系统故障,复原后须要从新生产 1 小时前的数据,那么 Broker 要提供一种机制,能够依照工夫维度来回退生产进度。
RocketMQ 反对依照工夫回溯生产,工夫维度准确到毫秒,能够向前回溯,也能够向后回溯。
音讯沉积
消息中间件的次要性能是异步解耦,还有个重要性能是挡住前端的数据洪峰,保障后端系统的稳定性,这就要求消息中间件具备肯定的音讯沉积能力,音讯沉积分以下两种状况:
- 音讯沉积在内存 Buffer,一旦超过内存 Buffer,能够依据肯定的抛弃策略来抛弃音讯,如 CORBA Notification 标准中形容。适宜能容忍抛弃音讯的业务,这种状况音讯的沉积能力次要在于内存 Buffer 大小,而且音讯沉积后,性能降落不会太大,因为内存中数据多少对于对外提供的拜访能力影响无限。
- 音讯沉积到长久化存储系统中,例如 DB,KV 存储,文件记录模式。当音讯不能在内存 Cache 命中时,要不可避免的拜访磁盘,会产生大量读 IO,读 IO 的吞吐量间接决定了音讯沉积后的拜访能力。
评估音讯沉积能力次要有以下四点:
- 音讯能沉积多少条,多少字节?即音讯的沉积容量。
- 音讯沉积后,发消息的吞吐量大小,是否会受沉积影响?
- 音讯沉积后,失常生产的 Consumer 是否会受影响?
- 音讯沉积后,拜访沉积在磁盘的音讯时,吞吐量有多大?
分布式事务
已知的几个分布式事务标准,如 XA,JTA 等。其中 XA 标准被各大数据库厂商广泛支持,如 Oracle,Mysql 等。其中 XA 的 TM 实现佼佼者如 Oracle Tuxedo,在金融、电信等畛域被广泛应用。
分布式事务波及到两阶段提交问题,在数据存储方面的方面必然须要 KV 存储的反对,因为第二阶段的提交回滚须要批改音讯状态,肯定波及到依据 Key 去查找 Message 的动作。RocketMQ 在第二阶段绕过了依据 Key 去查找 Message 的问题,采纳第一阶段发送 Prepared 音讯时,拿到了音讯的 Offset,第二阶段通过 Offset 去拜访音讯,并批改状态,Offset 就是数据的地址。
RocketMQ 这种实现事务形式,没有通过 KV 存储做,而是通过 Offset 形式,存在一个显著缺点,即通过 Offset 更改数据,会令零碎的脏页过多,须要特地关注。
定时音讯
定时音讯是指音讯发到 Broker 后,不能立即被 Consumer 生产,要到特定的工夫点或者期待特定的工夫后能力被生产。
如果要反对任意的工夫精度,在 Broker 层面,必须要做音讯排序,如果再波及到长久化,那么音讯排序要不可避免的产生微小性能开销。
RocketMQ 反对定时音讯,然而不反对任意工夫精度,反对特定的 level,例如定时 5s,10s,1m 等。
音讯重试
Consumer 生产音讯失败后,要提供一种重试机制,令音讯再生产一次。Consumer 生产音讯失败通常能够认为有以下几种状况:
- 因为音讯自身的起因,例如反序列化失败,音讯数据自身无奈解决(例如话费充值,以后音讯的手机号被登记,无奈充值)等。这种谬误通常须要跳过这条音讯,再生产其余音讯,而这条失败的音讯即便立即重试生产,99% 也不胜利,所以最好提供一种定时重试机制,即过 10s 秒后再重试。
- 因为依赖的上游应用服务不可用,例如 db 连贯不可用,外零碎网络不可达等。遇到这种谬误,即便跳过以后失败的音讯,生产其余音讯同样也会报错。这种状况倡议利用 sleep 30s,再生产下一条音讯,这样能够加重 Broker 重试音讯的压力。
RocketMQ Overview
RocketMQ 是否解决了上述消息中间件面临的问题,接下来让咱们一探到底。
RocketMQ 是什么?
上图是一个典型的消息中间件收发音讯的模型,RocketMQ 也是这样的设计,简略说来,RocketMQ 具备以下特点:
- 是一个队列模型的消息中间件,具备高性能、高牢靠、高实时、分布式特点。
- Producer、Consumer、队列都能够分布式。
- Producer 向一些队列轮流发送音讯,队列汇合称为 Topic,Consumer 如果做播送生产,则一个 consumer 实例生产这个 Topic 对应的所有队列,如果做集群生产,则多个 Consumer 实例均匀生产这个 topic 对应的队列汇合。
- 可能保障严格的音讯程序
- 提供丰盛的音讯拉取模式
- 高效的订阅者程度扩大能力
- 实时的音讯订阅机制
- 亿级音讯沉积能力
- 较少的依赖
RocketMQ 物理部署构造
如上图所示,RocketMQ 的部署构造有以下特点:
- Name Server 是一个简直无状态节点,可集群部署,节点之间无任何信息同步。
- Broker 部署绝对简单,Broker 分为 Master 与 Slave,一个 Master 能够对应多个 Slave,然而一个 Slave 只能对应一个 Master,Master 与 Slave 的对应关系通过指定雷同的 BrokerName,不同的 BrokerId 来定义,BrokerId 为 0 示意 Master,非 0 示意 Slave。Master 也能够部署多个。每个 Broker 与 Name Server 集群中的所有节点建设长连贯,定时注册 Topic 信息到所有 Name Server。
- Producer 与 Name Server 集群中的其中一个节点(随机抉择)建设长连贯,定期从 Name Server 取 Topic 路由信息,并向提供 Topic 服务的 Master 建设长连贯,且定时向 Master 发送心跳。Producer 齐全无状态,可集群部署。
- Consumer 与 Name Server 集群中的其中一个节点(随机抉择)建设长连贯,定期从 Name Server 取 Topic 路由信息,并向提供 Topic 服务的 Master、Slave 建设长连贯,且定时向 Master、Slave 发送心跳。Consumer 既能够从 Master 订阅音讯,也能够从 Slave 订阅音讯,订阅规定由 Broker 配置决定。
RocketMQ 逻辑部署构造
如上图所示,RocketMQ 的逻辑部署构造有 Producer 和 Consumer 两个特点。
Producer Group
用来示意一个发送音讯利用,一个 Producer Group 下蕴含多个 Producer 实例,能够是多台机器,也能够是一台机器的多个过程,或者一个过程的多个 Producer 对象。一个 Producer Group 能够发送多个 Topic 音讯,Producer Group 作用如下:
- 标识一类 Producer
- 能够通过运维工具查问这个发送音讯利用下有多个 Producer 实例
- 发送分布式事务音讯时,如果 Producer 中途意外宕机,Broker 会被动回调 Producer Group 内的任意一台机器来确认事务状态。
Consumer Group
用来示意一个生产音讯利用,一个 Consumer Group 下蕴含多个 Consumer 实例,能够是多台机器,也能够是多个过程,或者是一个过程的多个 Consumer 对象。一个 Consumer Group 下的多个 Consumer 以均摊形式生产音讯,如果设置为播送形式,那么这个 Consumer Group 下的每个实例都生产全量数据。
RocketMQ 数据存储构造
如上图所示,RocketMQ 采取了一种数据与索引拆散的存储办法。无效升高文件资源、IO 资源,内存资源的损耗。即使是阿里这种海量数据,高并发场景也可能无效升高端到端提早,并具备较强的横向扩大能力。