RocektMQ-CommitLog 刷盘

246 阅读2分钟

CommitLog 刷盘

提交刷盘可以看:CommitLog.submitFlushRequest()

CommitLog 同步刷盘

image.png

CommitLog 流程

  1. 消息写入 CommitLog 后给同步刷盘线程传入一个刷盘请求,放请求过程中需要加锁,请求中存放一个未执行的 CompletableFuture
  2. 唤醒刷盘线程
  3. 同步副本节点获取一个 CompletableFuture
  4. 等到 刷盘 CompletableFuture 与 同步副本 CompletableFuture 都执行完成的时候向生产者返回消息处理完成

GroupCommitService 流程

  1. 等待被唤醒或等待时间结束
  2. 上锁,交换读写队列,解锁
  3. 遍历读队列,进行刷盘
  4. 唤醒 CommitLog 传入的刷盘 CompletableFuture
  5. 修改 stroe 存储检查点
  6. 为读队列赋值一个新的队列

q:为什么刷盘刷两次?

a:CommitLog 是由多个 MappedFile 组成的,当有新消息存入但 MappedFile 空间不足时就会生成一个新的 MappedFile。但是刷盘指针不会变化,在刷盘过程中通过刷盘指针索引到的文件并没有包含新的消息,所以需要再次刷盘。

image.png

CommitLog 异步刷盘

image.png CommitLog 流程

  1. 消息写入 CommitLog 后给同步刷盘线程传入一个刷盘请求,放请求过程中需要加锁,请求中存放一个未执行的 CompletableFuture
  2. 唤醒刷盘线程
  3. 不用等待刷盘线程执行完成,直接返回一个执行成功的刷盘 CompletableFuture
  4. 等到 刷盘 CompletableFuture 与 同步副本 CompletableFuture 都执行完成的时候向生产者返回消息处理完成

GroupCommitService 流程

  1. 等待执行,两种模式
    • 模式1:固定等待 500ms
    • 模式2:被唤醒或等待 500ms
  2. 查看现在的时间距离上一次刷盘完成是否大于等于 10s
    • 大于等于 10s:直接进行刷盘
    • 小于 10s:查看内存中未刷盘数据大于等于 4 个系统页(4 * 4kb),是的话刷盘,否则跳过