当前位置: 首页 > news >正文

大白话聊明白:同步刷盘、异步刷盘以及RocketMQ和RabbitMQ的刷盘策略

关于作者:

         一个深耕自己,不内耗的长期主义者。一个对技术充满激情,对工作对生活充满热情的热血青年。坚信,真正能让大家看懂的技术文章才是好文章,坚持用通俗易懂的大白话写技术文章,并会持续更新。

今天来聊一下什么是同步刷盘、异步刷盘以及RocketMQ和RabbitMQ的刷盘策略。很多人可能背过概念,或者尝试着想去搞懂这些概念,可能已经看过N篇教程、视频,甚至还在面试中被狠狠问过,但总觉得还差一层窗户纸没捅破?别急,之前的文章一样,这次我依然用最通俗易懂的大白话来描述,带你搞定它。

理解同步刷盘和异步刷盘

一点都不难

讲之前,对涉及到的一些基础概念,必须要先了解清楚。想要了解什么是异步刷盘,什么是同步刷盘?需要对操作系统IO模型里的概念有一定了解,这些我之前的文章里都写过了:大白话聊懂IO的零拷贝技术还有大白话聊聊常见的IO模型:BIO、NIO和IO多路复用。里边比较详细的介绍了IO模型的内容。

别感觉很难,看我写的一点都不难。经常看我文章的应该都能感觉到,我写文章和其他人可能不一样,我都是循序渐进来写的。我会把我是怎么从不理解不明白,到最后是怎么搞明白的这个脉络,我会尽可能的用通俗易懂的大白话记录下来。我相信我自己是这么理解过来的,那大多数人按照我的脉络来看,肯定也都能看明白。希望能尽自己的一点绵薄之力,来帮更多人理解这些枯燥难懂的Java知识。

简述操作系统的IO模型

关于操作系统的IO模型,这里再大概简述一遍:就是操作系统为了保证安全,它把操作的内存分成了两部分:一部分是内核空间,一部分是用户空间。操作系统的内核程序运行在内核空间,除此之外所有用户的程序都运行在用户空间,比如咱们部署的程序全部都是运行在用户空间。

同样为了安全,用户空间运行的程序,不能访问内核空间中的数据,也不能直接调用内核函数或去操作底层硬件资源。所以如果要调用系统资源,就要从用户态切换到内核态,由内核程序来帮你完成操作。等操作完成后,需要从内核态切换回用户态,这就是咱们常说的状态切换。

用户态的程序需要和硬件交互时,需要从用户态切换到内核态,让内核程序帮你完成操作。内核程序它和底层硬件交互时,内核态会用缓冲区来存这些和硬件交互的数据。

因此,内核态的内核空间有两个数据缓冲区:一个叫内核缓冲区,也叫page cache,它缓存的是与磁盘交互的数据;另一个叫:Socket缓冲区,它缓存的是与网卡交互的数据。

咱们平时调用运行在用户空间的程序,想把数据持久化写入磁盘时,会先把数据写入内核态与磁盘交互的内核缓冲区,然后再由DMA把数据刷到磁盘。好,知道了以上的的概念后,再来讲什么是同步刷盘和异步刷盘。

同步刷盘

同步刷盘,就是当客户端调用运行在用户空间的程序进行写数据时,它是必须等数据写入内核态缓冲区page cache后,再由DMA把数据完全刷到磁盘后,再给客户端返回成功,这就是同步刷盘。

异步刷盘

异步刷盘,就是写数据时,它不是等数据完全刷到磁盘后再给客户端返回成功,它是数据只写到内核态的page cache缓冲区后,就立马给客户端返回成功,这就是异步刷盘。

理解了这些后,很容易就能理解,咱们平常说的很多中间件都会有自己默认的刷盘策略,也可以通过配置去修改这些中间件的刷盘策略。比如mysql、es、RocketMQ、RabbitMQ它们都有自己的刷盘策略。今天就先来讲一下RocketMQ、RabbitMQ的刷盘策略,后边有时间会讲一下mysql的刷盘策略。

RocketMQ和RabbitMQ的刷盘策略

RocketMQ刷盘策略

RocketMQ:默认是异步刷盘。就是消息投递时,当消息写入brocker机器的内核缓冲区page cache后,就给生产者返回成功投递了,默认500毫秒异步刷盘一次。

默认异步刷盘,但可通过配置改成同步刷盘。具体怎么改,这种小问题随便一搜就可以了,这里就不说了。这里只讨论怎么让你从根上理解这些更关键的内容。

RabbitMQ刷盘策略

RabbitMQ:默认不刷盘,不持久化。你创建交换机、队列时,如果不指定持久化,那rabbit它默认就不刷盘不持久化。你需要的持久化的话,那你创建交换机、队列时,都要配置上持久化的选项,然后投递消息时也要带着持久化的参数delivery_mode=2(持久化消息)。

这三个只要其中某一个没显式配置持久化,那消息就不会持久化,只在内存,不会刷盘,重启丢失。并且就算三个都配持久化了,RabbitMQ它默认是异步刷盘,并且只能异步刷盘,不能改,异步刷盘时间也不固定它会动态调整。

性能与数据完整性的权衡

现在大部分中间件,为了兼顾性能和数据完整性,都会去做一些权衡和取舍。你像RocketMQ用的是异步刷盘,500毫秒刷一次,在性能和数据完整性之间做了权衡,但两者也不能都兼得,所以极端情况下rocket会丢失500毫秒的数据。

如果你的业务接受不了,那就根据它官方的文档去修改配置,改成同步刷盘。改成同步刷盘后,数据完整性可以得到保障,但性能肯定会下降,因为同步刷盘,需要客户端连接等在那里,等数据完全刷入磁盘后才会给客户端返回成功,那并发高的情况下,就会有很多请求都等在那里。

但是也有厂商也会转换思路来优化。比如,mysql它提交事务时,虽然是同步刷盘,必须等待Redo log完全刷入磁盘后,才会给客户端返回事务提交成功。但是它把直接刷盘数据页这种有可能无序的随机写操作,转成了Redo log这种有序的顺序写操作,性能也会提升不少,并且Redo log还能完全的保证数据的完整性。

比如,还有RocketMQ消息投递时会把消息顺序追加写入commit Log和consume Queue文件,然后通过维护各个消费者组内各个消费者的消费进度,来实现一个消息可以被不同消费者组内的消费者去拉取消费。这都是通过把低效的随机写,转化成了高效的顺序写的操作,通过这种合理的设计能有效提高并发时的能力。

关于mysql具体的事务操作和事务提交时的刷盘策略,我会再写一篇具体展开来讲。RocketMQ生产者投递消息,具体是怎么写入文件的后边也会单独写一篇来分析。

OK,今天就先写到这,希望对你理解这几个关键的概念有所帮助。我坚信,真正能让大家看懂的技术文章才是好文章,这也是我最初决定写文章最主要的目标和动力,希望这篇文章对你有所帮助。欢迎留言讨论,后续会更新更多内容。

最后

纯手敲 原创不易,如果这篇文章对你有所启发或帮助,希望可以花费你一秒钟的时间,点亮【赞和推荐】,如果能点【分享】给更多同行的人,那就更好了。你的每一个互动,都是我持续创作的最大动力。感恩遇见,感谢陪伴。

http://www.dtcms.com/a/389509.html

相关文章:

  • I0流学习
  • 摄影灯MCU方案开发,摄影灯单片机分析
  • Salesforce知识点: LWC 组件通信全解析
  • Lua语言程序设计3:闭包、模式匹配、日期和时间
  • Freertos系列教学(删除函数的使用)
  • DevOps平台建设 - 总体设计文档的核心架构与关键技术实践
  • 系统中间件与云虚拟化-云数据库与数据库访问中间件ORM框架-Sannic-非实验
  • DTC BluSDR™系列-满足您所有的无人机通信需求
  • 【猛犸AI科技】深度强化学习SCI/EI/CCF/中文核心一站式辅导
  • 美创科技闪耀亚洲教育装备博览会,以数据安全护航教育数字化
  • 1.css的几种定位方式
  • 【C#】对比两个坐标点是否相同的多种方法
  • Ubuntu之旅-03 InfluxDB
  • IEEE出版,稳定检索!|2025年智能制造、机器人与自动化国际学术会议 (IMRA 2025)
  • iOS 上架流程详细指南 苹果应用发布步骤、ipa 文件上传 打包上架实战经验
  • MessageBus 通信组件库
  • 性能测试-jmeter12-万能插件包管理器jmeter-plugins
  • 工地项目管理系统有什么强大功能?工程企业实现数字化的步骤
  • 【开题答辩全过程】以 “萌崽”宠物社交小程序为例,包含答辩的问题和答案
  • Spring Cloud Alibaba微服务架构深度解析:基于Nacos、Gateway、OpenFeign与Sentinel的现代化实践
  • 大模型-Attention面试
  • Hadoop3.3.5搭建指南(简约版)
  • Python运算符与表达式
  • “双碳”目标下,塔能科技如何用“物联网精准节能”重塑城市能源生态?
  • 格恩朗气体涡轮流量计:精准计量每一方气,守护能源高效利用
  • 从感知机到多层感知机:深度学习入门核心知识解析
  • 从Java ArrayList 学习泛型设计
  • 【Amber报错1】 Amber/Miniconda 与系统 Bash 的 libtinfo.so.6冲突
  • AI智慧能力的核心引擎,自注意力机制
  • 35、模型量化与压缩实践