这篇文章上次修改于 899 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
文件系统是对存储设备上的文件进行统一管理的一种机制。Linux 在各种文件系统的基础上又抽象了一层虚拟文件系统 VFS。
VFS 内部通过超级块、逻辑块、索引节点和目录项等数据结构管理文件。其中,目录项是一个内存缓存,而超级块、逻辑块和索引节点是存储在磁盘上的。
1 磁盘
将磁盘按照存储介质分类:
- 机械盘,缩写为 HDD(Hard Disk Driver),由磁头和盘片组成,数据存储在环状磁道中。读写数据前,需将磁头定位到数据所在的磁道。随机 I/O 会导致磁头不断移动,读写速度较慢。
- 固态磁盘,缩写为 SSD(Solid State Disk),由固态电子元器件组成。因为不需要磁道寻址,所以性能比机械盘好。但也存在“先擦除再写入“的限制,所以随机 I/O 性能同样比连续 I/O 差。
按照使用方式,可分为多种架构:
- 直接作为独立磁盘设备使用。往往还会根据需要,划分为不同的逻辑分区,如 /dev/sda 可划分为 /dev/sda1 和 /dev/sda2。
- 将多个磁盘组合为一个逻辑磁盘,构成冗余独立磁盘阵列,即 RAID,可提高数据的访问性能和可靠性。
Linux 中,磁盘是作为块设备来管理的。拥有主设备号和次设备号,主设备号用来区分设备类型,次设备号区分同种设备。
2 通用块层
Linux 通过通用块层管理不同的块设备。
通用块层是位于磁盘驱动和文件系统之间的块设备抽象层。是磁盘 I/O 的核心。
它的功能包括:
- 提供统一接口,屏蔽细节。向上,为文件系统和应用程序提供访问设备的统一接口;向下,将各种异构的磁盘设备抽象为统一的块设备,并提供统一的框架管理这些设备的驱动程序。
- 将文件系统和应用程序的 I/O 请求排序,通过重新排序、请求合并等方式提高磁盘读写效率。
对 I/O 排序即为 I/O 调度,包括四种:
- NONE
- NOOP,先进先出,只对 I/O 请求进行基本的合并。
- CFQ(Completely Fair Scheduler),为每个进程维护了一个 I/O 调度队列,并按照时间片均匀分布每个进程的 I/O 请求。还支持优先级调整,适用于运行大量进程的系统,如桌面环境、多媒体应用等。
- Deadline,分别为读、写请求创建不同的 I/O 队列,可提高机械盘的吞吐量。适用于 I/O 压力比较重的场景,如数据库等。
3 I/O 栈
由上到下分为文件系统层、通用块层和设备层。
为了优化文件系统层访问性能,会使用页缓存、索引节点缓存、目录项缓存等多种缓存机制。
为了优化块设备访问性能,会使用缓冲区。
4 磁盘性能指标
包括五个指标:
- 使用率,磁盘处理 I/O 的时间百分比,超过 80% 时存在性能瓶颈。
- 饱和度,磁盘处理 I/O 的繁忙程度,达到 100% 时无法处理新的 I/O 请求。
- IOPS,每秒 I/O 请求数。在数据库、大量小文件等随机读写量大的场景中更能反应系统性能。
- 吞吐量,每秒 I/O 请求大小。在多媒体等顺序读读场景中更能反应系统性能。
- 响应时间,I/O 请求从发出到收到响应的间隔时间。
测试磁盘性能方式:不同 I/O 大小(一般是 512B 至 1MB 中间的若干值)分别在随机读、顺序读、随机写、顺序写等各种场景下的性能情况。
5 磁盘 I/O 观测
每块磁盘使用情况:
$ iostat -d -x 1
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 3.31 0.03 2.65 1.48 27.25 21.49 0.00 1.53 2.87 1.52 0.22 0.06
scd0 0.00 0.00 0.00 0.00 0.00 0.00 7.11 0.00 0.60 0.60 0.00 0.60 0.00
- r/s,w/s,每秒发送给磁盘的读、写请求数。
- rrqm/s,wrqm/s,每秒合并的读、写请求数。
- r_wait,w_ait,读、写请求处理完成等待时间,单位毫秒,包括队列中的等待时间和设备实际处理时间。
- %util,磁盘处理 I/O 的时间百分比,即使用率。
以上指标中:
- %util 为磁盘 I/O 使用率
- r/s + w/s 为 IOPS
- rkB/s + wkB/s 为吞吐量
- r_wait + w_ait 为响应时间
6 进程 I/O 观测
$ pidstat -d 1
22时41分22秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
22时41分23秒 0 29062 0.00 4.00 0.00 0 YDService
- kB_ccwr/s,每秒取消的写请求数据大小。
- iodelay,块 I/O 延迟,包括等待同步块 I/O 和换入块 I/O 结束的时间,单位是时钟周期。
iotop 可按照 I/O 大小对进程排序:
$ iotop
Total DISK READ : 0.00 B/s | Total DISK WRITE : 7.85 K/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
15055 be/3 root 0.00 B/s 7.85 K/s 0.00 % 0.00 % systemd-journald
参考
倪朋飞. Linux 性能优化实战.
没有评论