【操作系统】聊聊磁盘IO是如何工作的

news/2025/2/12 7:45:54/

磁盘

在这里插入图片描述

机械磁盘
主要是由盘片和读写磁头组成。数据存储在盘片的的环状磁道上,读写数据前需要移动磁头,先找到对应的磁道,然后才可以访问数据。
如果数据都在同一磁道上,不需要在进行切换磁道,这就是连续IO,可以获得更好的性能。而随机IO性能就比较差。

固态磁盘
固态磁盘不需要寻找磁道,所以随机IO和连续IO性能都不错。

连续IO的性能其实比随机IO性能要好,主要连续IO可以进行预读的操作,这是其中一个性能点,另外随机IO其实还是比连续IO差。

机械磁盘的最小单位是扇区,大小是512字节
固态磁盘的最小单位是页,通常是4KB

而对于机械磁盘,因为扇区单位比较小,为了尽可能提升顺序IO,将8个扇区组成一个4KB的页。

通用块层

通用块层是处于文件系统和磁盘驱动中间的一个块设备抽象层。

  • 对上层的文件系统提供统一块访问标准接口。对下层不同的磁盘设备抽象为统一的块设备。并提供统一的框架管理这些设备的驱动程序。
  • 通用块层会给应用程序和文件系统发送的IO请求排队,通过重排序、请求合并等方式。提高磁盘读写效率。

IO调度算法

  • NONE 什么也不做,磁盘IO调度由物理机完成。
  • NOOP 是一个先入先出的队列,做一些基本的请求合并
  • CFQ 完全公平调度器 为每个进程维护一个IO调度队列,并按照时间片均匀分布每个进程IO请求
  • DeadLine调度算法,为读写请求创建不同的IO队列,提高机械磁盘的吞吐量。

上述其实优点一个是队列,另一个是按照进程粒度进行分配IO请求,另一个就是按照读写粒度进行处理。你看无论是编程类库,还是存储中间件都是相同的思想。

在这里插入图片描述

IO栈

LinuxIO栈分为 文件系统层、通用块层、设备层。

在这里插入图片描述

  • 文件系统层,包含虚拟文件系统和其他文件系统的具体实现,为上层应用程序提供标准的文件访问接口,下层通过通用块层来存储和管理磁盘数据
  • 通用块层:块设备IO队列和IO调度器,对文件系统的IO请求进行排队,在通过重新排序和请求合并。
  • 设备层:存储设备和相关驱动程序,最终负责物理设备的IO操作。

存储系统的IO是最慢的地方,所以通过使用各种缓存机制来优化访问文件的性能,减少对下层块设备的直接调用。其中包含页缓存、目录项缓存、索引节点缓存。

磁盘IO观测

# -d -x表示显示所有磁盘I/O的指标
$ iostat -d -x 1 

在这里插入图片描述
在这里插入图片描述

  • %util ,就是我们前面提到的磁盘I/O使用率;
  • r/s+ w/s ,就是 IOPS;
  • rkB/s+wkB/s ,就是吞吐量;
  • r_await+w_await ,就是响应时间。

进程IO观测

$ pidstat -d 1 

在这里插入图片描述
用户ID(UID)和进程ID(PID) 。

每秒读取的数据大小(kB_rd/s) ,单位是 KB。

每秒发出的写请求数据大小(kB_wr/s) ,单位是 KB。

每秒取消的写请求数据大小(kB_ccwr/s) ,单位是 KB。

块I/O延迟(iodelay),包括等待同步块I/O和换入块I/O结束的时间,单位是时钟周期。

小结

本篇主要介绍了磁盘IO的工作原理,主要介绍了文件系统层、通用块层、设备层。而在操作系统内部其实也使用了各种的缓存来提升系统的IO读写效率。最后简要介绍来下常用的IO排查命令 iotop、pidstat -d 1 、iostat -d -x 1


http://www.ppmy.cn/news/1117741.html

相关文章

Lua 点 冒号面向对象 继承

1.点与冒号 self机制 local a {} function a.test() print("a.test") end a.test() local b {} function b:test() --self代表调用表的实例 print("b:test", self) end -- b:test() --self机制下a应该改为 b则不需要修改 local a {} function a.test(s…

【深度学习实验】前馈神经网络(三):自定义多层感知机(激活函数logistic、线性层算Linear)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集 2. 激活函数logistic 3. 线性层算子 Linear 4. 两层的前馈神经网络MLP 5. 模型训练 一、实验介绍 本实验实现了一个简单的两层前馈神经网络 激活函数…

【图像去噪】【TGV 正则器的快速计算方法】通过FFT的总(广义)变化进行图像去噪(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

mysql向数据库中添加数据

要向MySQL数据库中添加数据,您可以使用INSERT INTO语句。以下是一些基本步骤和示例代码来添加数据: 连接到数据库: 首先,您需要使用MySQL客户端或编程语言中的MySQL连接库连接到您的数据库。 编写INSERT语句: 创建一个…

C++中string对象之间比较、char*之间比较

#include <cstring> //char* 使用strcmp #include <string> //string 使用compare #include <iostream> using namespace std; int main() {string stringStr1 "42";string stringStr2 "42";string stringStr3 "213";cout …

QT-day4

画一个时钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPaintEvent> #include <QDebug> #include <QPainter> #include <QTimer> #include <QTime>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } Q…

使用Arduino简单测试HC-08蓝牙模块

目录 模块简介模块测试接线代码测试现象 总结 模块简介 HC-08 蓝牙串口通信模块是新一代的基于 Bluetooth Specification V4.0 BLE 蓝牙协议的数传模块。无线工作频段为 2.4GHz ISM&#xff0c;调制方式是 GFSK。模块最大发射功率为4dBm&#xff0c;接收灵度-93dBm&#xff0c…

【滑动窗口】LCR 016. 无重复字符的最长子串

LCR 016. 无重复字符的最长子串 解题思路 窗口内的字符串就是不重复子串每次遇到新的字符 看看窗口内是否存在该字符 如果存在直接剔除 然后调整窗口左边界不存在 添加窗口内部 右边界 class Solution {public int lengthOfLongestSubstring(String s) {if(s.length() < …