RocketMQ数据防丢失与刷盘、复制策略
讨论可靠性传输这个问题,我们需要从三个角度来分析:生产者弄丢数据、RocketMQ弄丢数据、消费者弄丢数据。
消费端弄丢了数据
对于消费端,如果我们在使用 Push 模式的情况下,只有我们消费返回成功,才会异步定期更新消费进度到 Broker 上。
如果消费端异常崩溃,可能导致消费进度未更新到 Broker 上,那么无非是 Consumer 可能重复拉取到已经消费过的消息。关于这个,就需要消费端做好消费的幂等性。
Broker 弄丢了数据?
我们首先来看看Broker的刷盘和复制方式。
刷盘
(1) 同步刷盘:如上图所示,只有在消息真正持久化至磁盘后RocketMQ的Broker端才会真正返回给Producer端一个成功的ACK响应。同步刷盘对MQ消息可靠性来说是一种不错的保障,但是性能上会有较大影响,一般适用于金融业务应用该模式较多。
(2) 异步刷盘:能够充分利用OS的PageCache的优势,只要消息写入PageCache即可将成功的ACK返回给Producer端。消息刷盘采用后台异步线程提交的方式进行,降低了读写延迟,提高了MQ的性能和吞吐量。
一般地,异步刷盘只有在 Broker 意外宕机的时候会丢失部分数据,你可以设置 Broker 的参数 FlushDiskType 来调整你的刷盘策略(ASYNC_FLUSH 或者 SYNC_FLUSH)。
同步复制和异步复制
如果一个broker组有Master和Slave,消息需要从Master复制到Slave上,有同步和异步两种复制方式。
同步复制: 也叫 “同步双写”,也就是说,只有消息同步双写到主从结点上时才返回写入成功 。
异步复制: 消息写入主节点之后就直接返回写入成功 。
复制方式 | 优点 | 缺点 | 适应场景 |
---|---|---|---|
同步复制 | slave保证了与master一致的数据副本,如果master宕机,数据依然在slave中找到其数据和master的数据一致 | 由于需要slave确认效率上会有一定的损失 | 数据可靠性要求很高的场景 |
异步复制 | 无需等待slave确认消息是否存储成功效率上要高于同步复制 | 如果master宕机,由于数据同步有延迟导致slave和master存在一定程度的数据不一致问题 | 数据可靠性要求一般的场景 |
通过上面的介绍,我们可以想到。如果要保证 Broker 数据最大化的不丢,需要在搭建 Broker 集群时,设置为同步刷盘、同步复制。当然,带来了可靠性,也会一定程度降低性能。
如果想要在可靠性和性能之间做一个平衡,可以选择,从 Broker 都是同步复制和异步刷盘。因为,刷盘比较消耗性能。
生产者会不会弄丢数据
Producer 可以设置三次发送消息重试。