原理

磁盘工作原理

持久化存储

文件系统工作原理

在磁盘的基础上提供管理文件的树状结构 Linux 为每个文件分配了两个数据结构索引节点(index node) 和 目录项(directory entry)

基准测试

磁盘I/O 基准测试工具 fio(Flexible I/O Tester):它提供了大量的可定制化选项,可以用来测试,裸盘或者文件系统在各种场景下的 I/O 性能,包括了不同块大小、不同 I/O 引擎以及是否使用缓存等场景。
fio 支持 I/O 重放,配合blktrace 实现精确模拟应用程序的 I/O 模式

  1. # 使用 blktrace 跟踪磁盘 I/O,注意指定应用程序正在操作的磁盘
  2. $ blktrace /dev/sdb
  3. # 查看 blktrace 记录的结果
  4. # ls
  5. sdb.blktrace.0 sdb.blktrace.1
  6. # 将结果转化为二进制文件
  7. $ blkparse sdb -d sdb.bin
  8. # 使用 fio 重放日志
  9. $ fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.bin

I/O 性能分析思路

iostat 发现磁盘 I/O 性能瓶颈 —> pidstat ,定位出导致瓶颈的进程 — —> 分析进程的 I/O 行为 —> 结合应用程序的原理,分析这些 I/O 的来源

I/O 性能优化思路

磁盘优化
文件系统优化
应用程序优化

概念

I/O 模式:

Linux 文件系统四大基本要素(数据结构):目录项、索引节点、逻辑块、超级块

  • 目录项,记录了文件的名字,以及文件与其他目录项之间的目录关系。
  • 索引节点,记录了文件的元数据。
  • 逻辑块,是由连续磁盘扇区构成的最小读写单元,用来存储文件数据。
  • 超级块,用来记录文件系统整体的状态,如索引节点和逻辑块的使用情况等。

其中目录项是内页缓存,索引节点、逻辑块、超级块是磁盘中持久化数据

文件系统:
索引节点
目录项
虚拟文件系统VFS(Virtual File System):
挂载点
文件系统I/O

Part Ⅳ | I/O 性能篇 - 图1

磁盘:
扇区:磁盘读写的最小扇区
逻辑块:

通用块层
I/O 栈

指标

Part Ⅳ | I/O 性能篇 - 图2

磁盘性能指标

使用率,指磁盘处理 I/O 的时间百分比
饱和度,指磁盘处理 I/O 的繁忙程度,当饱和度为 100% 时,磁盘无法接受新的 I/O 请求
IOPS(Input/Output Per Second),是指每秒的 I/O 请求数。
吞吐量,指每秒的 I/O 请求大小
响应时间,指 I/O 请求从发出到收到响应的间隔时间

文件系统性能指标

工具

磁盘I/O 基准测试 fio(Flexible I/O Tester)
磁盘容量使用情况 df
磁盘 I/O 观测 iostat
进程 I/O 观测 iotop、pidstat
文件系统缓存 /proc/meminfo、/proc/slabinfo、slabtop
内核系统调用追踪工具 strace
进程打开文件列表 lsof
内核中文件的读写 filetop
动态跟踪内核中的 open 系统调用 opensnoop

  1. # -f 表示跟踪子进程和子线程,-T 表示显示系统调用的时长,-tt 表示显示跟踪时间 -e 指定调用
  2. $ strace -f -T -tt -p 9085
  3. [pid 9085] 14:20:16.826131 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 65, NULL, 8) = 1 <0.000055>
  4. [pid 9085] 14:20:16.826301 read(8, "*2\r\n$3\r\nGET\r\n$41\r\nuuid:5b2e76cc-"..., 16384) = 61 <0.000071>
  5. [pid 9085] 14:20:16.826477 read(3, 0x7fff366a5747, 1) = -1 EAGAIN (Resource temporarily unavailable) <0.000063>
  6. [pid 9085] 14:20:16.826645 write(8, "$3\r\nbad\r\n", 9) = 9 <0.000173>
  7. [pid 9085] 14:20:16.826907 epoll_pwait(5, [{EPOLLIN, {u32=8, u64=8}}], 10128, 65, NULL, 8) = 1 <0.000032>
  1. # 输出了 8 列内容
  2. # 分别是线程 ID、线程命令行、读写次数、读写的大小(单位 KB)、文件类型以及读写的文件名称
  3. # 切换到工具目录
  4. $ cd /usr/share/bcc/tools
  5. # -C 选项表示输出新内容时不清空屏幕
  6. $ ./filetop -C
  7. TID COMM READS WRITES R_Kb W_Kb T FILE
  8. 514 python 0 1 0 2832 R 669.txt
  9. 514 python 0 1 0 2490 R 667.txt
  10. 514 python 0 1 0 2685 R 671.txt
  1. opensnoop
  2. 12280 python 6 0 /tmp/9046db9e-fe25-11e8-b13f-0242ac110002/650.txt

2019-08-29_144027.png


Part Ⅳ | I/O 性能篇 - 图4

Part Ⅳ | I/O 性能篇 - 图5

Linux 文件系统架构图(I/O栈图)

Part Ⅳ | I/O 性能篇 - 图6

Linux 存储系统 I/O 栈

Part Ⅳ | I/O 性能篇 - 图7