Linux I/O 性能分析 - 概念篇
2024-01-24 本文已影响0人
偏心念丶
Linux 文件系统原理
索引节点和目录项
在 Linux 中,一切皆文件,为了方便管理,Linux 文件系统为每个文件都分配两个数据结构,索引节点(index node)和目录项(directory entry)。它们主要用来记录文件的元信息和目录结构。
- 索引节点,简称为 inode,用来记录文件的元数据,比如 inode 编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以记住,索引节点同样占用磁盘空间。
-
目录项,简称为 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项,就构成了文件系统的目录结构。不过,不同于索引节点,目录项是由内核维护的一个内存数据结构,所以通常也被叫做目录项缓存。
如下图所示:
image.png
需要注意的是:
- 目录项本身就是一个内存缓存,而索引节点则是存储在磁盘中的数据,所以,索引节点也会缓存到内存中,从而加速文件的访问。
- 磁盘在执行文件系统格式化时,会被分成三个存储区域,超级块、索引节点区和数据块区。超级块,存储整个文件系统的状态。索引节点区,用来存储索引节点。数据块区,则用来存储文件数据。
虚拟文件系统
目录项、索引节点、逻辑块以及超级块,构成了 Linux 文件系统的四大基本要素。不过,为了支持各种不同的文件系统,Linux 内核在用户进程和文件系统的中间,又引入了一个抽象层,也就是虚拟文件系统 VFS(Virtual File System)。
image.png
文件系统的观测指标
容量
文件系统的磁盘空间使用情况
df -Th /dev/vda1
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 99G 77G 19G 81% /
另外,inode 也会占用磁盘空间
df -i /dev/vda1
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 6553600 1411937 5141663 22% /
缓存
实际上,内核使用 Slab 机制,管理目录项和索引节点的缓存。/proc/meminfo 只给出了 Slab 的整体大小,具体到每一种 Slab 缓存,还要查看 /proc/slabinfo 这个文件
cat /proc/slabinfo | grep -E '^#|dentry|inode'
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
nfs_inode_cache 7781 16590 1120 29 8 : tunables 0 0 0 : slabdata 590 590 0
ovl_inode 139738 160300 720 45 8 : tunables 0 0 0 : slabdata 3564 3564 0
rpc_inode_cache 920 920 704 46 8 : tunables 0 0 0 : slabdata 20 20 0
xfs_inode 329696 511911 1088 30 8 : tunables 0 0 0 : slabdata 17070 17070 0
fuse_inode 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0
mqueue_inode_cache 1054 1054 960 34 8 : tunables 0 0 0 : slabdata 31 31 0
udf_inode_cache 0 0 816 40 8 : tunables 0 0 0 : slabdata 0 0 0
isofs_inode_cache 987 987 688 47 8 : tunables 0 0 0 : slabdata 21 21 0
fat_inode_cache 0 0 776 42 8 : tunables 0 0 0 : slabdata 0 0 0
jbd2_inode 22819 50816 64 64 1 : tunables 0 0 0 : slabdata 794 794 0
ext2_inode_cache 0 0 864 37 8 : tunables 0 0 0 : slabdata 0 0 0
ext4_inode_cache 135042 265177 1152 28 8 : tunables 0 0 0 : slabdata 9609 9609 0
hugetlbfs_inode_cache 48 48 664 24 4 : tunables 0 0 0 : slabdata 2 2 0
inotify_inode_mark 52071 52275 80 51 1 : tunables 0 0 0 : slabdata 1025 1025 0
sock_inode_cache 74776 75040 832 39 8 : tunables 0 0 0 : slabdata 1925 1925 0
proc_inode_cache 217797 222471 712 46 8 : tunables 0 0 0 : slabdata 4839 4839 0
shmem_inode_cache 29175 31218 752 43 8 : tunables 0 0 0 : slabdata 726 726 0
inode_cache 176590 178181 640 25 4 : tunables 0 0 0 : slabdata 7128 7128 0
dentry 4171929 13868208 224 36 2 : tunables 0 0 0 : slabdata 385231 385231 0
其中,dentry 行表示目录项缓存,inode_cache 行,表示 VFS 索引节点缓存,其余的则是各种文件系统的索引节点缓存。
实际性能分析中,我们更常使用 slabtop ,来找到占用内存最多的缓存类型。
# 按下c按照缓存大小排序,按下a按照活跃对象数排序
$ slabtop
Active / Total Objects (% used) : 14703586 / 26109197 (56.3%)
Active / Total Slabs (% used) : 672727 / 672727 (100.0%)
Active / Total Caches (% used) : 187 / 273 (68.5%)
Active / Total Size (% used) : 3634188.87K / 6402995.95K (56.8%)
Minimum / Average / Maximum Object : 0.01K / 0.25K / 10.19K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
13884516 4184714 30% 0.22K 385684 36 3085472K dentry
512121 330274 64% 1.06K 17077 30 546464K xfs_inode
618562 325811 52% 0.57K 22108 28 353728K radix_tree_node
265177 135042 50% 1.12K 9609 28 307488K ext4_inode_cache
282828 270095 95% 1.00K 8855 32 283360K kmalloc-1k
1898550 1883641 99% 0.13K 63285 30 253140K kernfs_node_cache
223391 218976 98% 0.70K 4859 46 155488K proc_inode_cache
180631 179228 99% 0.62K 7226 25 115616K inode_cache
160300 139738 87% 0.70K 3564 45 114048K ovl_inode
844896 577538 68% 0.10K 21664 39 86656K buffer_head
7503 7213 96% 10.19K 2505 3 80160K task_struct
15976 15705 98% 4.00K 1997 8 63904K kmalloc-4k
199375 192826 96% 0.31K 7975 25 63800K filp
262412 260230 99% 0.23K 7718 34 61744K vm_area_struct
Linux磁盘 I/O
I/O性能指标
- 使用率,是指磁盘处理 IO 的时间百分比,过高的使用率(比如超过 80%),通常以为着磁盘 IO 存在着性能瓶颈。
- 饱和度,是指磁盘处理 IO 的繁忙程度,过高的磁盘饱和度意味着磁盘存在着严重的性能瓶颈,当饱和度为 100% 时,则意味着磁盘无法接受新的 IO 请求。
- IOPS,是指每秒的IO 请求数。
- 吞吐量,是指每秒的 IO 请求大小。
- 响应时间,是指 IO 请求从发出到接受响应的间隔时间。
I/O指标观测工具
iostat
iostat 是最常用的磁盘 I/O 性能观测工具,它提供了每个磁盘的使用率、IOPS、吞吐量等各种常见的性能指标,当然,这些指标实际上来自 /proc/diskstats。
-d -x表示显示所有磁盘I/O的指标
$ iostat -d -x 1
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
loop0 0.00 0.00 0.03 0.00 0.00 0.00 0.00 0.00 0.06 0.00 0.00 118.64 0.00 0.47 0.00
vda 2.54 25.39 16.88 291.39 0.62 23.70 19.73 48.29 0.76 1.46 0.02 6.65 11.48 0.91 2.53
vdb 0.11 4.21 7.68 101.42 0.00 0.63 0.44 13.08 2.39 3.91 0.01 69.19 24.09 1.02 0.44
指标说明:
- %util ,就是我们前面提到的磁盘 I/O 使用率;
- r/s+ w/s ,就是 IOPS;\
- rkB/s+wkB/s ,就是吞吐量;
- r_await+w_await ,就是响应时间。
进程 IO 观测
pidstat工具
pidstat -d 1
Linux 5.4.203-1-tlinux4-0011.1 (VM-167-17-tencentos) 01/27/2024 _x86_64_ (16 CPU)
08:18:40 AM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
08:18:41 AM 0 460 0.00 78.43 0.00 1 jbd2/vda1-8
08:18:41 AM 0 25009 0.00 3.92 0.00 0 containerd
08:18:41 AM 0 25653 0.00 70.59 0.00 0 etcd
08:18:41 AM 999 1236567 0.00 101.96 0.00 0 mysqld
- 用户 ID(UID)和进程 ID(PID) 。
- 每秒读取的数据大小(kB_rd/s) ,单位是 KB。
- 每秒发出的写请求数据大小(kB_wr/s) ,单位是 KB。
- 每秒取消的写请求数据大小(kB_ccwr/s) ,单位是 KB。
- 块 I/O 延迟(iodelay),包括等待同步块 I/O 和换入块 I/O 结束的时间,单位是时钟周期。
iotop工具
$ 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