Rocketmq 如何保证消息的可用性/可靠性/不丢失呢 ?

如何保证消息的可用性/可靠性/不丢失呢 ?

消息可能在哪些阶段丢失呢?可能会在这三个阶段发生丢失:生产阶段、存储阶段、消费阶段


生产阶段

在生产阶段,主要通过请求确认机制,来保证消息的可靠传递


1、同步发送的时候,要注意处理响应结果和异常。如果返回响应OK,表示消息成功发送到了Broker,如果响应失败,或者发生其它异常,都应该重试


2、异步发送的时候,应该在回调方法里检查,如果发送失败或者异常,都应该进行重试,并可以设置重试次数


3、如果发生超时的情况,也可以通过查询日志的API,来检查是否在Broker存储成功


存储阶段

存储阶段,可以通过配置可靠性优先的 Broker 参数来避免因为宕机丢消息,简单说就是可靠性优先的场景都应该使用同步


1、消息只要持久化到 CommitLog(日志文件)中,即使Broker宕机,未消费的消息也能重新恢复再消费。


2、Broker的刷盘机制:同步刷盘和异步刷盘,不管哪种刷盘都可以保证消息一定存储在pagecache中(内存中),但是同步刷盘更可靠,它是Producer发送消息后等数据持久化到磁盘之后再返回响应给Producer


同步刷盘

只有在消息真正持久化至磁盘后RocketMQ的Broker端才会真正返回给Producer端一个成功的ACK响应。同步刷盘对MQ消息可靠性来说是一种不错的保障,但是性能上会有较大影响,一般适用于金融业务应用该模式较多


异步刷盘(默认)

能够充分利用OS的PageCache的优势,只要消息写入PageCache即可将成功的ACK返回给Producer端。消息刷盘采用后台异步线程提交的方式进行,降低了读写延迟,提高了MQ的性能和吞吐量


3、Broker通过主从模式来保证高可用,Broker支持 Master 和 Slave同步复制、Master 和 Slave异步复制模式,生产者的消息都是发送给Master,但是消费既可以从Master消费,也可以从Slave消费。

同步复制模式可以保证即使Master宕机,消息肯定在Slave中有备份,保证了消息不会丢失。


Broker支持Master 和 Slave 复制,如果一个 Broker 组有 Master 和 Slave,消息需要从 Master 复制到 Slave 上,有同步和异步两种复制方式:


a、同步复制方式:Master 和 Slave 均写成功后才反馈给客户端写成功状态。在同步复制方式下,如果 Master 出故障, Slave 上有全部的备份数据,容易恢复,但是同步复制会增大数据写入延迟,降低系统吞吐量


b、异步复制方式:只要 Master 写成功,即可反馈给客户端写成功状态,系统拥有较低的延迟和较高的吞吐量,但是如果 Master 出了故障,有些数据因为没有被写入 Slave,有可能会丢失


消费阶段

a、手动提交消息应答

使用手动提交可以确保消息被正确处理后再提交应答

b、幂等性消费

在消费端实现幂等性处理,确保重复消费不会导致业务问题


总结

RocketMQ通过以下方式保证消息不丢失:

1、生产端:同步发送、异步发送 + 重试、事务消息

2、Broker端:同步刷盘、搭建Broker集群实现主从复制

3、消费端:手动提交应答、消息重试、幂等性消费

posted @ 2024-11-13 22:37  jock_javaEE  阅读(59)  评论(0)    收藏  举报