RocketMQ5.1.3依然存在刷盘bug,可能导致消息丢失

之前4.8.0时,发过文章《RocketMQ 刷盘机制BUG踩坑——可能引起消息丢失》,说明了可能导致消息丢失的bug。有兴趣可以看看。

后来社区一直没改,我们就自己修复了,之后也没太关注新版本。

最近考察5版本,发现问题依旧。直接附代码DefaultMappedFile.java的flush方法。下面依然是catch了代码后没有做任何处理。

public int flush(final int flushLeastPages) {
        if (this.isAbleToFlush(flushLeastPages)) {
            if (this.hold()) {
                int value = getReadPosition();

                try {
                    this.mappedByteBufferAccessCountSinceLastSwap++;

                    //We only append data to fileChannel or mappedByteBuffer, never both.
                    if (writeBuffer != null || this.fileChannel.position() != 0) {
                        this.fileChannel.force(false);
                    } else {
                        this.mappedByteBuffer.force();
                    }
                    this.lastFlushTime = System.currentTimeMillis();//这里的lastFlushTime并没有用到
                } catch (Throwable e) {//这里依然是catch了,但是没有做任何操作
                    log.error("Error occurred when force data to disk.", e);
                }

                FLUSHED_POSITION_UPDATER.set(this, value);
                this.release();
            } else {
                log.warn("in flush, hold failed, flush offset = " + FLUSHED_POSITION_UPDATER.get(this));
                FLUSHED_POSITION_UPDATER.set(this, getReadPosition());
            }
        }
        return this.getFlushedPosition();
    }

这就导致如果刷盘超时,是可以捕获的。但如果是刷盘直接报错,输出一条日志就完了,返回给客户端的还是SEND_OK。此时做个服务器重启,数据就丢了。

不过不得不承认,5版本可以自动切换主从,这样的话主节点丢失的数据从节点还有。但如果你想用单点的架构,那么消息丢失就是要考虑的点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值