美文网首页
RocketMQ 数据丢失问题解决

RocketMQ 数据丢失问题解决

作者: 发光的鱼 | 来源:发表于2020-07-13 10:52 被阅读0次

    1. 问题

    当向RocketMQ频繁push数据,broker负载较高时,会报system busy或broker busy的问题。当发生此类问题时,会导致数据丢失。

    报system busy或broker busy 说明PageCache繁忙,向PageCache追加消息时,单个消息发送占用的时间超过一定时间,如果持续往该Broker服务器发送消息并等待,超时后,broker采用快速失败机制返回失败信息。

    解决这种问题需要对RocketMQ进行配置调优,提升RocketMQ的吞吐能力。

    2. 参数调优

    默认情况下RocketMQ的broker的数据读写没有进行分离。

    可以通过在broker.conf中将transientStorePoolEnable=true,开启读写分离。启用“读写”分离,消息发送时消息先追加到DirectByteBuffer(堆外内存)中,然后在异步刷盘机制下,会将DirectByteBuffer中的内容提交到PageCache,然后刷写到磁盘。消息拉取时,直接从PageCache中拉取,实现了读写分离,减轻了PageCaceh的压力,能从根本上解决该问题。

    开启分离后,有一些风险,会增加数据丢失的可能性,如果Broker JVM进程异常退出,提交到PageCache中的消息是不会丢失的,但存在堆外内存(DirectByteBuffer)中但还未提交到PageCache中的这部分消息,将会丢失。但通常情况下,RocketMQ进程退出的可能性不大。

    开启读写分离后,有一些相关的参数也需要调整,比如提交消息时开启重入锁,增大发送的超时。

    broker.conf修改如下:

    useReentrantLockWhenPutMessage=true
    osPageCacheBusyTimeOutMills=5000
    waitTimeMillsInSendQueue=3000
    transientStorePoolEnable=true
    transientStorePoolSize=2
    

    同时,需要注意transientStorePoolSize这个参数,这个是堆外缓存池大小,这个这个默认为5,配置成5需要占用5G空间,配置成2就占用2G空间,需要根据生产环境机器配置情况调整。同时,broker的JVM也需要作相应调整,保证有足够的堆外内存可用。

    修改,runbroker.sh

    JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=4g"
    

    相关文章

      网友评论

          本文标题:RocketMQ 数据丢失问题解决

          本文链接:https://www.haomeiwen.com/subject/hgqacktx.html