文件系统以及磁盘I/O理论
一. 上节回顾
内存溢出的问题定位
二. 文件系统以及磁盘I/O
1. 概念
磁盘和文件系统管理,是操作系统最核心的功能之一
磁盘:提供了最基本的持久化存储
文件系统:是在磁盘的基础上,提供了一个用来管理文件的树状结构
2. 索引节点和目录项
我们都知道,在Linux中一切皆是文件,不仅普通的文件和目录,连块设备,套接字,管理等,也都要通过统一的文件系统来管理。为了方便管理,Linux系统为每个文件都分配了两个数据结构:索引节点(index node)和目录项(directory entry)
索引节点:简称为iNode,用来记录文件的元数据,比如iNode编号,文件大小,访问权限,修改日期,数据位置等,索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中,所以索引节点同样占用磁盘空间
目录项:简称dentry,索引节点指针以及与其他目录项的关联关系
可以简单地说,索引节点是每个文件的唯一标志,而目录项维护的正是文件系统的树状结构,目录项和索引节点的关系是多对一,也就是:一个文件可以有多个别名
从上图可以得出两个结论:
第一:目录项本身就是一个内存缓存,而索引节点则是存储在磁盘中的数据,这些索引节点自然会缓存到内存中,加速文件的访问
第二:磁盘在执行这些文件系统格式化时,会被分成三个存储区域:超级快,索引节点和数据块区
超级块:存储整个文件系统的状态
索引节点:用来存储索引节点
数据块区:用来存储文件数据
3. 虚拟文件系统
Linux文件系统的四大基本要素:目录项、索引节点、逻辑块以及超级块
为了支持不同的文件系统,Linux内核在用户进程和文件系统的中间,加入了虚拟文件系统
通过这张图,可以看到Linux支持各种的文件系统,比兔Ext4,XFS,NFS等,按照存储的不同位置,文件系统可以分为三类:
一:基于磁盘的文件系统,比如Ext4,XFS
二:基于内存的文件系统,比如:/proc,/sys
三:是网络文件系统,用来访问其他计算机数据的文件系统,比如:NFS,SMB
4. 文件系统I/O
虚拟文件系统提供了一组标准的文件访问接口,这些接口以系统调用的方式,提供给应用程序使用。比如:cat命令,它的执行过程是,先调用open()打开一个文件,然后调用read(),读取文件的内容,最后再调用write(),把文件内容输出到控制台
根据文件读写方式的差异,I/O也会有不同的分类,比如:
第一种:根据是否利用标准库缓存,可以把文件I/O分为缓冲I/O和非缓冲I/O
缓冲I/O:利用标准库缓存来加速文件的访问,而标准库内部再通过系统调度访问文件
非缓冲I/O:直接通过调用来访问文件,不再经过标准库缓存
这里说的"缓冲",是指标准库内部实现的缓存,比如很多程序遇到换行时才真正输出,而换行前的内容,其实就是被标准库暂时缓存起来
第二种:根据是否利于操作系统的页缓存,可以把文件I/O分为直接I/O和非直接I/O
直接I/O:指跳过操作系统的页缓存,直接跟文件系统交互来访问文件
非直接I/O:正好相反,文件读写时,先要经过操作系统页缓存,然后再用内核或额外的系统调用,真正写入磁盘
第三种:根据应用程序是否阻塞自身运行,可以把文件I/O分为阻塞I/O和非阻塞I/O
阻塞I/O:指应用程序执行I/O操作后,如果没有获得响应,就会阻塞当前线程,自然就不能执行其他任务
非阻塞I/O:指应用程序执行I/O操作后,不会阻塞当前的线程,可以继续执行其他任务,随后再通过轮询或者事件通知的形式,获取调用结果
第四种:根据是否等待响应结果,可以把文件I/O分为同步和异步I/O
同步I/O:指应用程序执行I/O操作后,要一直等到整个I/O完成后,才能获得I/O响应
异步I/O:指应用程序执行I/O操作后,不用等待完成和完成后的响应,而是继续执行下面的操作
5. 磁盘容量和磁盘分类
(1) 磁盘容量
查看磁盘容量的命令:def -h /dev/sda1
(2) 磁盘分类
磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘,固态磁盘
机械磁盘:也称为硬盘驱动器,简写HDD,机械磁盘主要是由盘片和读写磁头组成,数据就存储在盘片的环装磁道中,在读写数据前,需要移动读写磁头,定位到数据所在的磁道,然后才能访问数据,需要寻址
固态磁盘:简写SSD,由固态电子元器件组成,固态磁盘不需要磁道寻址,所以不管是连续I/O还是随机I/O的性能,都比机械磁盘要好很多
除了磁盘本身的分类,当你把磁盘接入服务器后,按照不同的使用方式,又可以把他们分为不同的架构,最简单的,就是直接作为独立磁盘设备来使用,这些磁盘,往往还会根据需要,划分为不同的逻辑分区,每个分区再用数据编号,比如:/dev/sda,可以分为:/dev/sda1,/dev/sda2
根据容量,性能和可靠性需求的不同,又可以进行Raid划分:raid0,raid1,raid5,raid10
raid0:有最优的读写性能,但不提供数据冗余的功能
其他级别的raid,在提供数据冗余的基础上,对读写性能也有一定程度的优化
6. 通用块层
在Linux中,磁盘实际上是作为一个块设备来管理的,也就是以块为单位读写数据,并且支持随机读写
通用块层:是处于文件系统和磁盘驱动中间的一个块设备抽象层,功能:
第一个:跟虚拟文件系统的功能类似,向上为文件系统和应用程序,提供块设备的标准接口,向下把各种异构的磁盘抽象为统一的块设备,并提供统一框架来管理这些设备的驱动程序
第二个:通用块层还会给文件系统和应用程序发来的I/O请求排队,并通过重新排序,请求合并等方式,提高磁盘读写的效率
7. I/O栈
Linux存储系统的I/O栈,由上到下分为三个层次,分别是文件系统层,通用块层和设备层
存储系统I/O的工作原理(重点):
文件系统层:包括虚拟文件系统和其他各种文件系统的具体实现,它为上层的应用程序提供标准的文件访问接口,对下会通过通用块层,来存储和管理磁盘数据
通用块层:包括块设备I/O队列和I/O调度器,它会对文件系统的I/O请求进行排队,再通过重新排序和请求合并,然后才要发送给一级设备层
设备层:包括存储设备和响应的驱动程序,负责最终物理设备的I/O操作
存储系统的I/O,通常是整个系统中最慢的一个环节,所以Linux系统通过多种缓存机制来优化I/O效率
三. 磁盘性能指标
1. 磁盘的性能有哪些指标?
主要由五个指标:使用率、饱和度、IOPS、吞吐量和响应时间
使用率:指磁盘处理I/O的时间百分比,超过80%意味着磁盘I/O存在性能瓶颈
饱和度:指磁盘处理I/O的繁忙程度,过高的饱和度,意味着磁盘存在严重的性能瓶颈,当饱和度为100%,磁盘无法接收新的请求
IOPS(input/output per second):指每秒的I/O请求数
吞吐量:指每秒I/O出路请求大小
吞吐时间:指I/O请求发出到接收到响应的间隔时间
2. 命令工具
(1) iostat
iostat -x 3
r/s:每秒发送给磁盘的读请求数
w/s:每秒发送给磁盘的写请求数
rKB/s:每秒从磁盘读取的数据量,单位:KB
wKB/s:每秒从磁盘写入的数据量,单位:KB
rrqm/s:每秒合并的读请求数
wrqm/s:每秒合并的写请求数
%rrqm:合并读请求的百分比
%wrqm:合并写请求的百分比
r_await:读请求处理完成等待时间
w_await:写请求处理完成等待时间
rareq-sz:平均读请求大小
wareq-sz:平均写请求大小
aqu-sz:平均请求队列长度
%util:磁盘处理I/O的时间百分比,就是磁盘I/O的使用率
在这些指标中,需要重点关注的是:
%util:磁盘处理I/O的时间百分比,就是磁盘I/O的使用率
r/s:每秒发送给磁盘的读请求数
w/s:每秒发送给磁盘的写请求数
r/s和w/s就是IOPS
rKB/s:每秒从磁盘读取的数据量,单位KB
wKB/s:每秒从磁盘写入的数据量,单位KB
rKB/s和KB/s就是吞吐量
r_await:读请求处理完成等待时间
w_await:写请求处理完成等待时间
r_await和w_await就是响应时间