索引文件的刷盘并不是采取定时刷盘机制,而是每更新一次索引文件就会将上一次的改动刷写到磁盘。

同步刷盘:

GroupCommitRequest将被提交到GroupCommitService线程,GroupCommitService线程处理GroupCommitRequest对象后将调用wakeupCustomer方法将消费发送线程唤醒。并将刷盘告知GroupCommitRequest。

这里将写操作和读操作做了分离,避免了任务提交与任务执行的锁冲突

GroupCommitService每处理一批同步刷盘请求后休息10ms,然后继续处理下一批,其任务的核心实现为doCommit方法:

CommitLog.this.mappedFileQueue.flush最终调用MappedByteBuffer#force()方法。

处理完所有同步刷盘任务后,更新刷盘检查点StoreCheckPoint中的physicMsgTimestamp,但是并没有执行检查点的刷盘操作,检查点的刷盘操作将在刷写消息队列文件时触发。

异步刷盘

CommitRealTimeService线程默认每200ms将ByteBuffer新追加的内容的数据提交到MappedByteBuffer中:

FlushRealTimeService线程默认每500ms将MappedByteBuffer中新最佳的内存(wrotePosition减去上一次刷写位置flushedPositiont)通过调用MappedByteBuffer#force()方法将数据刷写到磁盘:

  1. class FlushRealTimeService extends FlushCommitLogService {
  2. private long lastFlushTimestamp = 0;
  3. private long printTimes = 0;
  4.  
  5. public void run() {
  6. CommitLog.log.info(this.getServiceName() + " service started");
  7.  
  8. while (!this.isStopped()) {
  9. boolean flushCommitLogTimed = CommitLog.this.defaultMessageStore.getMessageStoreConfig().isFlushCommitLogTimed();
  10.  
  11. int interval = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushIntervalCommitLog();
  12. int flushPhysicQueueLeastPages = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushCommitLogLeastPages();
  13.  
  14. int flushPhysicQueueThoroughInterval =
  15. CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushCommitLogThoroughInterval();
  16.  
  17. boolean printFlushProgress = false;
  18.  
  19. // Print flush progress
  20. long currentTimeMillis = System.currentTimeMillis();
  21. if (currentTimeMillis >= (this.lastFlushTimestamp + flushPhysicQueueThoroughInterval)) {
  22. this.lastFlushTimestamp = currentTimeMillis;
  23. flushPhysicQueueLeastPages = 0;
  24. printFlushProgress = (printTimes++ % 10) == 0;
  25. }
  26.  
  27. try {
  28. if (flushCommitLogTimed) {
  29. Thread.sleep(interval);
  30. } else {
  31. this.waitForRunning(interval);
  32. }
  33.  
  34. if (printFlushProgress) {
  35. this.printFlushProgress();
  36. }
  37.  
  38. long begin = System.currentTimeMillis();
  39. CommitLog.this.mappedFileQueue.flush(flushPhysicQueueLeastPages);
  40. long storeTimestamp = CommitLog.this.mappedFileQueue.getStoreTimestamp();
  41. if (storeTimestamp > 0) {
  42. CommitLog.this.defaultMessageStore.getStoreCheckpoint().setPhysicMsgTimestamp(storeTimestamp);
  43. }
  44. long past = System.currentTimeMillis() - begin;
  45. if (past > 500) {
  46. log.info("Flush data to disk costs {} ms", past);
  47. }
  48. } catch (Throwable e) {
  49. CommitLog.log.warn(this.getServiceName() + " service has exception. ", e);
  50. this.printFlushProgress();
  51. }
  52. }
  53.  
  54. // Normal shutdown, to ensure that all the flush before exit
  55. boolean result = false;
  56. for (int i = 0; i < RETRY_TIMES_OVER && !result; i++) {
  57. result = CommitLog.this.mappedFileQueue.flush(0);
  58. CommitLog.log.info(this.getServiceName() + " service shutdown, retry " + (i + 1) + " times " + (result ? "OK" : "Not OK"));
  59. }
  60.  
  61. this.printFlushProgress();
  62.  
  63. CommitLog.log.info(this.getServiceName() + " service end");
  64. }

【mq读书笔记】mq索引文件刷盘的更多相关文章

  1. 【mq读书笔记】如何保证三个消息文件的最终一致性。

    考虑转发任务未成功执行,此时消息服务器Broker宕机,导致commitlog,consumeQueue,IndexFile文件数据不一致. commitlog,consumeQueue遍历每一条消息 ...

  2. 【mq读书笔记】mq消息存储

    comitlog文件 ConsumerQueue文件 IndexFile文件 RocketMQ将所有主题的消息存储在同一个文件中,确保消息发送时顺序写文件. 为了提高消息消费的效率RocketMQ引入 ...

  3. 【mq读书笔记】消息消费队列和索引文件的更新

    ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...

  4. 【mq读书笔记】Index索引文件

    1.IndexHeader头部,40字节,记录IndexFile的统计信息: begainTimestamp:该索引文件中包含消息的最小存储时间 endTimestamp:该索引文件中包含消息的最大存 ...

  5. 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)

    在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...

  6. 【mq读书笔记】消息队列负载与重新分配(分配 新队列pullRequest入队)

    回顾PullMessageService#run: 如果队列总没有PullRequest对象,线程将阻塞. 围绕PullRequest有2个问题: 1.PullRequest对象在什么时候创建并加入p ...

  7. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  8. 【mq读书笔记】mq事务消息

    关于mq食物以什么样的方式解决了什么样的问题可以参考这里: https://www.jianshu.com/p/cc5c10221aa1 上文中示例基于mq版本较低较新的版本中TransactionL ...

  9. 【mq读书笔记】消息过滤机制

    mq支持表达式过滤和类过滤两种模式,其中表达式又分为TAG和SQL92.类过滤模式允许提交一个过滤类到FilterServer,消息消费者从FilterServer拉取消息,消息经过FilterSer ...

随机推荐

  1. 想买保时捷的运维李先生学Java性能之 垃圾收集器

    前言 垃圾收集算法是内存回收的方法论:垃圾收集器是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商.不同版本的虚拟机所提供的垃圾收集器都有很大的差别,并且 ...

  2. mshadow入门指南

    mshadow是一个基于表达式模板实现的张量库,在MXNet框架中被广泛使用.这篇文章简单介绍了mshadow的基本用法和特性,文章主要翻译自mshadow/guide/README. 张量数据结构 ...

  3. Java学习的第二十一天

    1.综合实例 error异常:error指的是错误,通常是程序员不可能通过代码来解决的问题,底层环境或硬件问题,也就是说在程序中用户不用捕获error及任何error子类的异常. exception指 ...

  4. 1.DRF初始化

    1.DRF框架的8个核心功能   1.认证(用户登录校验用户名密码或者token是否合法) 2.权限(根据不同的用户角色,可以操作不同的表) 3.限流(限制接口访问速度) 4.序列化(返回json) ...

  5. python模块导入(包)

    模块 关注公众号"轻松学编程"了解更多. 1.1. 模块的概述 ​ 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里的代码就会越来越长,越来越不容易维护. 为了编写可维 ...

  6. 读书笔记:《数据结构与算法分析Java语言描述》

    目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...

  7. NodeJs 加入Windows开机自启动服务

    首先需要到http://nssm.cc/download/?page=download 下载 nssm,下下来之后是压缩包形式的解压之后,在命令行模式下进入到nssm的目录.之后运行:nssm ins ...

  8. 简单了解JSON Web令牌(JWT)

    什么是JWT JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信任,因为它 ...

  9. 你还再为下载jar包慢而烦恼吗?Maven配置阿里云镜像

    Maven配置阿里云镜像 为什么我们下载jar这么慢 maven默认会从中央仓库下载jar包,这个仓库在国外,而且全世界的人都会从这里下载,所以下载速度肯定是非常慢的. 解决方案使用镜像 什么是镜像? ...

  10. 1,github更新问题

    赶去吃饭,不排版了. 一:上传 1,新建仓库 通过下面代码克隆仓库到本地: git clone https://github.com/ndnmonkey/zhihu.git 把文件放到克隆到本地的文件 ...