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

Linux之文件IO前世今生

在 Linux之文件系统前世今生(一) VFS中,我们提到了文件的读写,并给出了简要的读写示意图,本文将分析文件I/O的细节。
在这里插入图片描述

一、Buffered I/O(缓存I/O)& Directed I/O(直接I/O)

1.1、Page Cache

我们读写一个文件时,会从磁盘加载文件到内存中,以便我们快速读写文件;我们把内存中用于缓存文件的这块区域记为 Page CachePage Cache 位于内核态(所以也叫OS cache)。

  • page 是内存管理分配的基本单位, Page Cache 由多个 page 构成;
  • page 在操作系统中通常为 4KB 大小,而 Page Cache 的大小则为 4KB 的整数倍;
  • 更多 page 细节参见 Linux之内存管理前世今生(一)。

1.2、预读

根据程序的局部性原理,加载文件时除了加载文件指定位置内容,同时会加载该位置后续一部分连续内容到内存中,这个机制就是预读。所以 Page Cache 中额外包含了程序后续可能读写的内容。

1.2.1、Page Cache + 预读优势

  • 加速数据访问

    由于内存访问比磁盘访问快的多,且预读了后续数据;

  • 提高系统磁盘I/O吞吐量

    通过一次 I/O 将多个 page 装入 Page Cache 能够减少磁盘 I/O 次数, 进而提高系统磁盘 I/O 吞吐量;

1.3、Write back(写回)& Write Through(写穿)

由于我们在内核态引入的Page Cache机制,所以我们对文件的读写都是基于Page Cache,但文件最终还是需要持久化到磁盘中去的。Linux 提供两种策略将Page Cache脏页(dirty page) 刷回磁盘:

  • Write back(写回)
    • 内核线程周期性地将脏页刷回磁盘,Linux 默认采用此策略 ;
    • 该策略存在数据丢失的风险(比如遇到系统宕机、断电),理论上操作系统不宕机,数据就保证会刷回磁盘,即使用户程序崩溃;
  • Write Through(写穿)
    • 向用户层提供特定接口,应用程序可主动调用接口来直接刷新数据到磁盘
    • 以牺牲系统 I/O 吞吐量作为代价,向上层应用确保一旦写入,数据就已经落盘,不会丢失;

1.3.1、Page Cache刷盘涉及的系统调用

Write back(写回)& Write Through(写穿)这两种写策略均依赖系统调用,分为如下3种:

  • sync()

    将所有修改过的缓冲区排入写队列,然后就返回了,它并不等实际的写磁盘的操作结束。所以它的返回并不能保证数据的安全性。通常会有一个update系统守护进程每隔30s调用一次sync。

  • fsync(fd)
    • fd 代表的文件的脏数据和文件属性全部刷新至磁盘中;
    • 确保一直到写磁盘操作结束才会返回。数据库一般使用 fsync
  • fdatasync(fd)
    • fd 代表的文件的脏数据刷新至磁盘,fdatasync的功能与fsync类似,但是仅仅在必要的情况下才会同步文件属性,因此可以减少一次IO写操作;
    • 举例来说,文件的尺寸(st_size)如果变化,是需要立即同步的,否则OS一旦崩溃,即使文件的数据部分已同步,由于文件属性没有同步,依然读不到修改的内容。而最后访问时间(atime)/修改时间(mtime)是不需要每次都同步的,只要应用程序对这两个时间戳没有苛刻的要求,基本无伤大雅。

1.3.2、Write back 刷盘时机

  • Page Cache 脏页数量超过设定阈值;
  • Page Cache 脏页缓存超过设定缓存时间;
  • 应用程序主动刷盘,即调用 sync()fdatasync(fd)fsync(fd) 三者任一;
  • 物理内存分配告警;

1.4、Buffered I/O(缓存I/O)& Directed I/O(直接I/O)

  • 前面我们在内核态引入了Page Cache用于加速文件I/O的操作就是 Buffered I/O(缓存I/O)

在这里插入图片描述

  • 相反,如果在内核态关闭Page Cache的使用(通过参数O_DIRECT),文件I/O直接与磁盘交互,我们称为Directed I/O(直接I/O)

在这里插入图片描述

问题来了:Page Cache 这么好,什么场景需要关闭?

  • Page Cache 位于内核态,对用户态提供的API灵活性差,用户态的应用程序无法对Page Cache 进行个性化定制,比如什么时间刷盘,刷哪些数据……
  • Page Cache 容量受限,大文件读写时,很快会把Page Cache消耗完,导致之前缓存的常用的、热点数据被移出内存,下次访问热点数据时产生磁盘I/O,从而降低系统性能;即Page Cache 缓存的是小文件的热点数据。
  • 举例:Mysql 中 InnoDB :
    • Buffer Pool 关闭了Page Cache,即不在内核态缓存数据,直接在用户态缓存数据;
    • redo log buffer 通过参数innodb_flush_log_at_trx_commit(取值为0,1,2)设置为2来开启 Page Cache。

二、Blocking I/O(阻塞I/O)& Non Blocking I/O(非阻塞I/O)

  • 前面我们从 Page Cache 的维度,将 I/O分为 缓存I/O 和 直接I/O;
  • 接下来,我们从进程阻塞阶段的维度,将 I/O 分为 阻塞I/O 和 非阻塞I/O;

2.1、阻塞定义

阻塞 的主体是进程当进程进入阻塞状态,是不占用CPU资源的

2.2、阻塞时机

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使当前进程由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,所以只有处于运行态(获得CPU)的进程,才可能将其转为阻塞状态。

2.3、阻塞I/O

由前面定义,I/O时期待的事件未发生,产生阻塞,那到底期待啥呢?

等待内核将数据准备好,换言之,等待 Page Cache 中有程序请求的数据。

以文件读取为例:当一个read操作发生时,它会经历两个阶段:

第一阶段:等待数据准备 (Waiting for the data to be ready)。

第二阶段:将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。

2.3.1、阻塞I/O vs 非阻塞I/O

当应用程序发起read时,且Page Cache 中没有程序请求的数据时,内核会加载磁盘数据,若加载数据同时,

  • read调用立即返回告诉程序,数据没有准备好,这就是非阻塞I/O

    非阻塞 I/O 在I/O执行的第二个阶段仍然被阻塞了。

  • 相反,内核闷声干活,直到数据加载完,并且数据从内核拷贝到应用程序中,才返回,这就是阻塞I/O

    阻塞 I/O 在I/O执行的两个阶段都被阻塞了。

在这里插入图片描述

在这里插入图片描述

三、同步 I/O(synchronous I/O)& 异步 I/O(asynchronous I/O)

POSIX(Portable Operating System Interface, 可移植操作系统接口)关于同步I/O和异步I/O的定义如下:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;

An asynchronous I/O operation does not cause the requesting process to be blocked;

在这里插入图片描述

说人话就是,同步I/O会阻塞进程,异步I/O不会阻塞进程
我们之前提到的 阻塞I/O 和 非阻塞I/O 都是同步I/O

  • 阻塞I/O 两个阶段都阻塞;
  • 非阻塞I/O 第二个阶段阻塞;

四、小节

  • Page Cache 的维度,将 I/O分为 缓存I/O 和 直接I/O;
  • 进程阻塞阶段的维度,将 I/O 分为 阻塞I/O 和 非阻塞I/O;
  • 进程阻塞的维度,将 I/O 分为 同步I/O 和 异步I/O。

文件 I/O 至此基本介绍完毕,后续会介绍网络 I/O。

相关文章:

Linux之文件IO前世今生

在 Linux之文件系统前世今生(一) VFS中,我们提到了文件的读写,并给出了简要的读写示意图,本文将分析文件I/O的细节。 一、Buffered I/O(缓存I/O)& Directed I/O(直接I/O&#…...

如何在Windows中配置MySQL?

MySQL是一个广泛使用的开源关系型数据库管理系统,它支持多种操作系统平台,其中包括Windows。无论是开发者进行本地开发,还是管理员为应用程序配置数据库,MySQL都是一个非常流行的选择。本篇文章将详细介绍如何在Windows操作系统中…...

Kafka 入门与实战

一、Kafka 基础 1.1 创建topic kafka-topics.bat --bootstrap-server localhost:9092 --topic test --create 1.2 查看消费者偏移量位置 kafka-consumer-groups.bat --bootstrap-server localhost:9092 --describe --group test 1.3 消息的生产与发送 #生产者 kafka-cons…...

数学知识学习1

1、数论 1质数判定 i<n/i优化O(sqrt(n)) bool is_prime(int n){if(n<2)return false;for(int i2;i<n/i;i){if(n%i0)return false;} true; } 分解质因数 i<n/i优化O(sqrt(n)) // 定义一个函数 divide&#xff0c;接收一个整数 n 作为参数&#xff0c;用于分解质…...

【AI日记】25.02.08

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】【AI应用】 探索 AI 应用探索周二有个面试&#xff0c;明后天打算好好准备一下&#xff0c;我打算主要研究下 AI 如何在该行业赋能和应用&#xff0c;以及该行业未来的发展前景和公司痛点&#…...

Lecture8 | LPV VXGI SSAO SSDO

Review: Lecture 7 | Lecture 8 LPV (Light Propagation Volumes) Light Propagation Volumes(LPV)-孤岛惊魂CryEngine引进的技术 LPV做GI快|好 大体步骤&#xff1a; Step1.Generation of Radiance Point Set Scene Representation 生成辐射点集的场景表示&#xff1a;辐射…...

Java中实现定时锁屏的功能(可以指定时间执行)

Java中实现定时锁屏的功能&#xff08;可以指定时间执行&#xff09; 要在Java中实现定时锁屏的功能&#xff0c;可以使用java.util.Timer或java.util.concurrent.ScheduledExecutorService来调度任务&#xff0c;并通过调用操作系统的命令来执行锁屏。下面我将给出一个基本的…...

Java集合List详解(带脑图)

允许重复元素&#xff0c;有序。常见的实现类有 ArrayList、LinkedList、Vector。 ArrayList ArrayList 是在 Java 编程中常用的集合类之一&#xff0c;它提供了便捷的数组操作&#xff0c;并在动态性、灵活性和性能方面取得了平衡。如果需要频繁在中间插入和删除元素&#xf…...

[实验日志] VS Code 连接服务器上的 Python 解释器进行远程调试

目录 0. 前言 1. 环境 2. 准备工作 2.1 安装VS Code 2.2 安装插件 2.3 配置远程服务器 2.4 修改设置 2.5 打开远程调试窗口 3. 调试代码 3.1 输密码 3.2 打开服务器文件夹 3.3 配置Python环境 3.4 调试Python代码 补充&#xff1a;使用调试控制台&#xff0c;查看…...

(14)gdb 笔记(7):以日志记录的方式来调试多进程多线程程序,linux 命令 tail -f 实时跟踪日志

&#xff08;44&#xff09;以日志记录的方式来调试多进程多线程程序 &#xff1a; 这是老师的日志文件&#xff0c;可以用来模仿的模板&#xff1a; &#xff08;45&#xff09;实时追踪日志的 tail -f 命令&#xff1a; &#xff08;46&#xff09; 多种调试方法结合起来用 …...

Sentinel的安装和做限流的使用

一、安装 Release v1.8.3 alibaba/Sentinel GitHubA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) - Release v1.8.3 alibaba/Sentinelhttps://github.com/alibaba/Senti…...

四柱预测学

图表 后天八卦 十二地支不仅代表了时间,还代表了方位。具体来说: ‌子‌:代表正北方‌丑寅‌:合起来代表东北方‌卯‌:代表正东方‌辰巳‌:合起来代表东南方‌午‌:代表正南方‌未申‌:合起来代表西南方‌酉‌:代表正西方‌戌亥‌:合起来代表西北方‌四季-五行-六神…...

【个人开发】macbook m1 Lora微调qwen大模型

本项目参考网上各类教程整理而成&#xff0c;为个人学习记录。 项目github源码地址&#xff1a;Lora微调大模型 项目中微调模型为&#xff1a;qwen/Qwen1.5-4B-Chat。 去年新发布的Qwen/Qwen2.5-3B-Instruct同样也适用。 微调步骤 step0: 环境准备 conda create --name fin…...

sqli-labs靶场实录(二): Advanced Injections

sqli-labs靶场实录: Advanced Injections Less21Less22Less23探测注入点 Less24Less25联合注入使用符号替代 Less25aLess26逻辑符号绕过and/or过滤双写and/or绕过 Less26aLess27Less27aLess28Less28aLess29Less30Less31Less32&#xff08;宽字节注入&#xff09;Less33Less34Le…...

Linux系统 环境变量

环境变量 写在前面概念查看环境变量main函数的参数argc & argvenv bash环境变量 写在前面 对于环境变量&#xff0c;本篇主要介绍基本概念及三四个环境变量 —— PATH、HOME、PWD。其中 PATH 作为 “ 敲门砖 ”&#xff0c;我们会更详细讲解&#xff1b;理解环境变量的全局…...

机器学习-线性回归(最大似然估计)

机器学习任务可以分为两类: 一类是样本的特征向量 &#x1d499; 和标签 &#x1d466; 之间存在未知的函数关系&#x1d466; h(&#x1d499;)&#xff0c;另一类是条件概率&#x1d45d;(&#x1d466;|&#x1d499;)服从某个未知分布。最小二乘法是属于第一类&#xff0c…...

【信息系统项目管理师-案例真题】2017上半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题1】8 分【问题2】4 分【问题3】8 分【问题4】5 分试题二【问题1】10 分【问题2】8 分【问题3】6 分【问题4】5 分试题三【问题1】5 分【问题2】7 分【问题3】6 分【问题4】3 分试题一 阅读下列说明…...

CSP晋级组比赛生成文件夹与文件通用代码Python

快速生成文件夹与文件的脚本 import sys import osmyfiles sys.argv[1::] for f in myfiles:os.mkdir(f)os.system(f"touch {f}/{f}.in")os.system(f"touch {f}/{f}.out")os.system(f"touch {f}/{f}.cpp")with open("template.cpp",…...

正则表达式进阶(二)——零宽断言详解:\b \B \K \z \A

在正则表达式中&#xff0c;零宽断言是一种非常强大的工具&#xff0c;能够在不消费字符的情况下对匹配位置进行约束。除了环视&#xff08;lookahead 和 lookbehind&#xff09;以外&#xff0c;还有一些常用的零宽断言&#xff0c;它们用于处理边界、字符串的开头和结尾等特殊…...

Android 中实现 PDF 预览三种方式

目录 1. 使用第三方库 PdfRenderer&#xff08;适用于 Android 5.0 及以上&#xff09; 步骤&#xff1a;2. 使用第三方库 MuPDF步骤&#xff1a;3. 使用第三方库 PdfiumAndroid步骤&#xff1a; 1. 使用第三方库 PdfRenderer&#xff08;适用于 Android 5.0 及以上&#xff09…...

尚硅谷课程【笔记】——大数据之Zookeeper【二】

课程视频&#xff1a;【尚硅谷Zookeeper教程】 四、Zookeeper实战 4.1分布式安装部署 1. 集群规划 在Hadoop102、Hadoop103和Hadoop104三个节点上部署Zookeeper 2. 解压安装 1&#xff09;解压Zookeeper.tar.gz到指定目录 tar -zxvf zookeeper-3.7.2.tar.gz -C /opt/mod…...

CodeGPT + IDEA + DeepSeek,在IDEA中引入DeepSeek实现AI智能开发

CodeGPT IDEA DeepSeek&#xff0c;在IDEA中引入DeepSeek 版本说明 建议和我使用相同版本&#xff0c;实测2022版IDEA无法获取到CodeGPT最新版插件。&#xff08;在IDEA自带插件市场中搜不到&#xff0c;可以去官网搜索最新版本&#xff09; ToolsVersionIntelliJ IDEA202…...

postgresql 游标(cursor)的使用

概述 PostgreSQL游标可以封装查询并对其中每一行记录进行单独处理。当我们想对大量结果集进行分批处理时可以使用游标&#xff0c;因为一次性处理可能造成内存溢出。 另外我们可以定义函数返回游标类型变量&#xff0c;这是函数返回大数据集的有效方式&#xff0c;函数调用者…...

计算机组成原理——指令系统(六)

在时间的长河中&#xff0c;我们都是追梦人&#xff0c;脚下的每一步都在刻画未来的模样。无论世界如何变幻&#xff0c;心中的那团火焰都不应熄灭。它是你突破黑暗、迎接黎明的力量源泉。每一个不曾起舞的日子&#xff0c;都是对生命的辜负&#xff1b;每一次跌倒后的站起&…...

Python设计模式 - 原型模式

定义 原型模式是一种创建型设计模式&#xff0c;它可以通过复制现有对象来创建新对象&#xff0c;而不是直接实例化新的对象。 结构 抽象原型&#xff08;Prototype&#xff09;&#xff1a;声明 clone() 方法&#xff0c;以便派生类实现克隆自身的能力。具体原型&#xff08…...

金和OA C6 DownLoadBgImage任意文件读取漏洞

金和OA C6 DownLoadBgImage任意文件读取漏洞 漏洞描述 金和C6数据库是一款针对企业信息化管理而设计的高级数据库管理系统&#xff0c;主要应用于企业资源规划&#xff08;ERP&#xff09;、客户关系管理&#xff08;CRM&#xff09;以及办公自动化&#xff08;OA&#xff09…...

【stm32学习】STM32F103实操primary(FlyMCU)

github插入图片实在是太难用了&#xff0c;暂时懒得学就先用CSDN吧hh 一、在设备管理器下&#xff0c;找到单片机&#xff0c;并检查与FlyMCU-搜索端口 显示的是否一致 二、在搜索串口右面的栏里选中该Port&#xff0c;波特率选中115200 三、选择文件夹中的.hex文件&#xff0…...

如何将Excel的表格存为图片?

emmm&#xff0c;不知道题主具体的应用场景是什么&#xff0c;就分享几个我一般会用到的场景下奖excel表格保存为图片的技巧吧&#xff01; 先来个总结&#xff1a; 方法 适用场景 画质 操作难度 截图&#xff08;WinShiftS&#xff09; 快速保存表格&#xff0c;方便粘贴…...

51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤

一、Keil uVision5创建工程步骤 1.点击项目&#xff0c;新建 2.新建目录 3.选择目标机器&#xff0c;直接搜索at89c52选择&#xff0c;然后点击OK 4.是否添加起吊文件&#xff0c;一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键&#xff0c;添加…...

AUTOSAR面试题集锦(1)

最基础概念 什么是AUTOSAR?AUTOSAR到底做了什么? AUTOSAR,即汽车开放系统架构,是一套专门用于汽车的开放性的框架和行业标准,旨在标准化汽车开发的流程。 AUTOSAR 通过标准化软件接口、交换格式和方法论等内容,主要实现以下几个目标: 1. 使软件和硬件彼此独立,让应…...