• 源码分析RocketMQ之Broker-内存映射刷盘流程


    源码分析RocketMQ之Broker-内存映射刷盘流程
    内存映射:MappedFileQueue.getLastMappedFile
    属性:
    storePath:文件存储路径
    mappedFileSize:单个MappedFile文件长度
    CopyOnWriteArrayList<MappedFile> mappedFiles:mappedFile集合
    allocateMappedFileService:创建 MappedFileService服务线程
    flushedWhere:刷盘位置
    committedWhere:commit(已提交)位置
    storeTimestamp:存储时间
    内存映射文件MappedFileQueue 组织一系列MappedFile,在MappedFileQueue 队尾的通常是刚写满的或者还有部分
    空间或者是刚分配的MappedFile,每次写操作都通过getLastMappedFile拿到最后一个MappedFile进行写操作。
    MappedFile 通过 AllocateMappedFileService 进行文件的创建操作。

    MappedFile
    属性变量:
    TOTAL_MAPPED_VIRTUAL_MEMORY:当前jvm实例中MappedFile虚拟内存
    TOTAL_MAPPED_FILES:当前jvm实例中MappedFile对象个数
    wrotePosition:写入指针
    committedPosition:提交指针
    flushedPosition:刷写指针
    fileSize:单个文件的大小
    fileChannel:文件通道
    writeBuffer:写入buffer,如果开启了 transientStorePoolEnable 时不为空,writeBuffer 使用堆外内存,消息先进入到堆外内存中
                 然后通过Commit线程提交到内存映射buffer中,再通过Flush线程将数据持久化到磁盘中
    transientStorePool:writeBuffer 池,只有在开启 transientStorePoolEnable 时生效,默认为5个
    mappedByteBuffer:内存映射,操作系统的 PageCache
    firstCreateInQueue:是否MappedFileQueue队列中第一个文件

    Producer发送消息给broker的消息保存到MappedFile中,然后通过刷盘机制同步到磁盘中
    刷盘分为同步刷盘和异步刷盘,刷盘操作通过MappedFile.commit和MappedFile.flush,MappedFile.flush 
    通过fileChannel.force或者mappedByteBuffer.force()进行实际的刷盘动作
    MappedFile.appendMessage 完成消息写入
    1、获取写入位置
    2、判断是否开启写入缓冲池,如果writeBuffer不为空,则优先写入writeBuffer,否则写入mappedByteBuffer
    3、定位当前位置开始
    4、对消息进行编码,然后将编码后的数据写入这里得到的buteBuffer等待刷盘
    5、记录写入到的位置
    6、更新存储时间
    7、返回消息结果

    MappedFile.commit 
    1、如果 writeBuffer 等于null,则表示 IO 操作都是直接基于 FileChannel,所以此时返回当前可写的位置
    2、判断是否可以执行提交操作
    3、如果可以执行 commit0 
      1、这里使用 slice 方法,主要是用的同一片内存空间,但单独的指针
      2、将 bytebuf 当前 上一次 commitedPosition + 当前写位置这些数据全部写入到 FileChannel中
      3、fileChannel.write(byteBuffer) :commit 的作用原来是将writeBuffer 中的数据写入到 FileChannel 中
      4、更新committedPosition的位置
    MappedFile.flush 调用 FileChannel 或 MappedByteBuffer 的 force 方法

    单个commitlog文件,默认大小为1G,由多个commitlog文件来存储所有的消息,commitlog文件的命名以该文件在
    整个commitlog中的偏移量来命名,如:
     第一个文件: 00000000000000000000
     第二个文件: 00000000000000001024
    MappedFile 封装一个一个的commitlog文件,而MappedFileQueue 就是封装一个逻辑的commitlog文件,mappedFiled队列,从小到大排列
    使用内存映射机制,MappedByteBuffer 具体封装类为MappedFile
    同步刷盘,每次发送消息,都直接存储在MapFile 的 mappdByteBuffer,然后调用force()方法刷写到磁盘,等到 force 刷盘成功后,
    再返回调用方GroupCommitRequest#waitForFlush,这就是同步调用实现
    异步刷盘
    分为两种情况是否开启堆外内存池
    开启 消息追加时,放入writeBuffer 然后定时commit 到 FileChannel,然后定时flush。
    不开启 消息追加时,直接存入 MappedByteBuffer(pageCache) 中,然后定时 flush

  • 相关阅读:
    有效需求分析培训梳理(二)
    【分享】5G+北斗RTK高精度人员定位解决方案
    每日算法刷题Day7-比较字符串大小,去掉多余的空格,单词替换
    OAuth2.0第三方授权原理与实战
    【CNN-SVM回归预测】基于CNN-SVM实现数据回归预测附matlab代码
    03、MongoDB -- MongoDB 权限的设计
    订单。。。
    VS2019 Qt源码编译
    华为云云耀云服务器L实例评测 | 实例场景体验之搭建接口服务:通过华为云云耀云服务器构建 API 服务
    Qt应用开发(基础篇)——复选按钮 QCheckBox 单选按钮 QRadioButton
  • 原文地址:https://blog.csdn.net/liangshf520/article/details/125475527