Linux文件系统和磁盘I/O性能小结
Contents
一 一切皆文件
在Unix/Linux系统中,一切皆文件。包括文件,文件夹(路径),Socket,块设备都被当作文件来管理和维护。
二 文件组成部分
Linux系统把每个文件分为2个部分:索引节点index node简写inode;目录项directory entry,简写为dentry。前者主要用于记录文件的元数据信息,如文件名,权限,创建时间等。后者,记录文件和其它文件的关系。为了提升对文件的访问性能,操作系统通常会对它们进行缓存,即索引节点缓存和目录项缓存。
三 如何查看扇区大小和文件系统块大小
通常磁盘的扇区大小是512B,文件系统的块大小是4kb,即8个磁盘扇区。
查看磁盘扇区大小,fdisk -l; Sector size (logical/physical): 512 bytes / 512 bytes
[root@ky_app1 ~]# fdisk -l Disk /dev/sda: 214.7 GB, 214748364800 bytes, 419430400 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x000bc5db Device Boot Start End Blocks Id System /dev/sda1 * 2048 419430366 209714159+ 83 Linux [root@ky_app1 ~]#
查看文件系统块大小:tune2fs或者blockdev命令。
[root@ky_app1 ~]# tune2fs -l /dev/sda1|grep 'Block size' Block size: 4096 [root@ky_app1 ~]# blockdev --report /dev/sda RO RA SSZ BSZ StartSec Size Device rw 8192 512 4096 0 214748364800 /dev/sda [root@ky_app1 ~]# blockdev --getbsz /dev/sda 4096 [root@ky_app1 ~]# blockdev --help
Oracle数据块大小,以前在学习和使用Oracle的过程中,官方说一个Oracle的block通常是多个操作系统的块大小。如下:
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> show parameter db_block_size;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL>
四 虚拟文件系统
Linux可以支持不同的文件系统类型(ext3,ext4,xfs等),内核在用户空间和文件系统之间,引入了一个抽象层,Virtual FileSystem。VFS定义了通用的和标准的接口,用户进程或应用程序不需要关心底层的文件系统类型具体是什么,只需要按照我这个标准和接口来跟我通信,我负责和底层的文件系统交互。这样相当于是解耦了用户进程和文件系统之间的限定关系。VFS为用户空间和内核空间提供了通信的桥梁和纽带。
五 文件系统I/O方式分类
- 缓冲/非缓冲IO:是否通过操作系统标准库调用来执行I/O操作;
- 直接/非直接IO:是否经过系统也缓存来执行IO操作。比如:早年Oracle的裸设备就属于直接IO方式。
- 阻塞/非阻塞IO:调用方发起IO请求操作之后,如果一直等待返回结果,其它啥事儿也不干,就相当于把自己阻塞了,阻塞式IO;否则,发起请求之后,该干嘛干嘛,即非阻塞式IO;
- 同步/异步IO:被调用方对IO请求立即应答,给出一个响应,这是同步IO;异步IO指的是,先给调用方一个响应请求,接下来的IO操作我再慢慢处理,这是异步。Oracle DATAGUARD的最大保护模式可以类比看做是同步IO模式,主库的事务提交必须要求备库也提交完成才算成功。异步IO则可以看做是DATAGUARD的最高性能模式。
六 文件系统性能的2个指标
1 容量
分别通过df -Th或者是df -i来查看。需要注意的是inode也会占用磁盘空间,有时候明明磁盘空间还足够,但是提示IO失败,有可能是文件系统的inode被用完了,即大磁盘存了非常非常多的小文件。如下:
[root@ecs-public2 ~]# df -Th Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 40G 18G 21G 46% / tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm /dev/vdb ext4 197G 65G 123G 35% /data [root@ecs-public2 ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/vda1 2621440 2621440 0 100% / tmpfs 1007674 1 1007673 1% /dev/shm /dev/vdb 13107200 1704 13105496 1% /data [root@ecs-public2 ~]# pwd /root [root@ecs-public2 ~]#
2 缓存
我们在使用free命令的时候,看到的缓存内存,其实就是源于/etc/meminfo中的cache和可回收的slab内存值。
[root@ky_app1 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@ky_app1 ~]# free total used free shared buff/cache available Mem: 16265804 9352196 166240 75072 6747368 6500272 Swap: 0 0 0 [root@ky_app1 ~]# cat /proc/meminfo |grep -E "SReclaimable|Cached|Slab" Cached: 6298004 kB SwapCached: 0 kB Slab: 391164 kB SReclaimable: 340580 kB [root@ky_app1 ~]#
如果是CentOS 6的系统,由于内存算法不一样,对应的值也不同,free看到的cached完全等于/proc/meminfo中的Cached值:
[root@localhost ~]# cat /etc/redhat-release CentOS release 6.5 (Final) [root@localhost ~]# uname -rm 2.6.32-431.el6.x86_64 x86_64 [root@localhost ~]# free total used free shared buffers cached Mem: 8060900 7910252 150648 0 515512 4778716 -/+ buffers/cache: 2616024 5444876 Swap: 8208376 1124444 7083932 [root@localhost ~]# cat /proc/meminfo |grep -E "SReclaimable|Cached|Slab" Cached: 4778716 kB SwapCached: 31316 kB Slab: 163636 kB SReclaimable: 130056 kB [root@localhost ~]#
七 如何查看inode和dentry的缓存
inode和dentry缓存值源于/proc/slabinfo。我们可以:
1 cat /proc/slabinfo|grep -E ‘^#|dentry|inode’
[root@localhost ~]# 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> ext4_inode_cache 15137 15168 1016 4 1 : tunables 54 27 8 : slabdata 3792 3792 0 mqueue_inode_cache 1 4 896 4 1 : tunables 54 27 8 : slabdata 1 1 0 isofs_inode_cache 0 0 640 6 1 : tunables 54 27 8 : slabdata 0 0 0 hugetlbfs_inode_cache 1 6 608 6 1 : tunables 54 27 8 : slabdata 1 1 0 inotify_inode_mark_entry 126 136 112 34 1 : tunables 120 60 8 : slabdata 4 4 0 sock_inode_cache 140 170 704 5 1 : tunables 54 27 8 : slabdata 34 34 0 shmem_inode_cache 877 885 784 5 1 : tunables 54 27 8 : slabdata 177 177 0 proc_inode_cache 983 990 656 6 1 : tunables 54 27 8 : slabdata 165 165 0 inode_cache 4331 4374 592 6 1 : tunables 54 27 8 : slabdata 729 729 0 dentry 18184 19620 192 20 1 : tunables 120 60 8 : slabdata 981 981 0 selinux_inode_security 7906 8162 72 53 1 : tunables 120 60 8 : slabdata 154 154 0 [root@localhost ~]#
从输出结果中,可以看到inode_cache和dentry行分别表示索引缓存和目录项缓存信息。
2 slabtop
[root@localhost ~]# slabtop Active / Total Objects (% used) : 970667 / 1010775 (96.0%) Active / Total Slabs (% used) : 37708 / 37713 (100.0%) Active / Total Caches (% used) : 98 / 184 (53.3%) Active / Total Size (% used) : 144210.79K / 149694.51K (96.3%) Minimum / Average / Maximum Object : 0.02K / 0.15K / 4096.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 807377 790758 97% 0.10K 21821 37 87284K buffer_head 34790 32481 93% 0.55K 4970 7 19880K radix_tree_node 27199 15562 57% 0.06K 461 59 1844K size-64 19620 18158 92% 0.19K 981 20 3924K dentry 19488 19197 98% 0.03K 174 112 696K size-32 15168 15137 99% 0.99K 3792 4 15168K ext4_inode_cache 11666 11478 98% 0.20K 614 19 2456K vm_area_struct
进入slabtop之后,可以根据不同的排序方法,对结果进行排序输出,比如按下键盘的a,表示按照active 对象排序(默认),c表示对缓存大小排序。具体使用方式,可以man slabtop。
八 磁盘IO最小单位
hdd磁盘默认最小IO单位是1个扇区,512B字节;
ssd磁盘默认最小IO单位是1个页,通常是4kb或者是8kb.
九 磁盘IO storage stack
操作系统在文件系统和底层的存储设备层之间,抽象了1个通用块层。它接收上层的文件系统的IO请求,然后交到底层的设备层去执行真正的IO操作,这么做的好处是:
对上:把上层文件系统IO请求进行整理封装,按照特定的调度算法来完成IO请求,
对下:不管底层的设备层是什么类型,什么接口的设备,都统一封装进行IO操作;
通用块层是 Linux 磁盘 I/O 的核心。向上,它为文件系统和应用程序,提供访问了块设备的标准接口;向下,把各种异构的磁盘设备,抽象为统一的块设备,并会对文件系统和应用程序发来的 I/O 请求,进行重新排序、请求合并等,提高了磁盘访问的效率。
十 磁盘性能指标
- 利用率:磁盘处理IO的时间百分比。过高(80%)意味着磁盘性能问题;
- 饱和度:磁盘处理IO的繁忙程度。若达到100%,意味着磁盘不能再接收新的IO请求;
- IOPS:IO Per Second,磁盘每秒接收的IO请求次数;
- throughout:吞吐量。磁盘每秒IO请求的大小;
- latency:从接收到IO请求到完成时间。
十一 如何观测磁盘IO
1 iostat -d -x 1
在1台CentOS 7的物理机上,通过cp1个文件,来监测磁盘IO:
session1: 执行cp /ssd/bcdir/debug.log /ssd2/,相当于把/dev/sdc1设备下的文件cp到/dev/sda1设备。
[root@centos-master ~]# df -Th 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/VolGroup-lv_root ext4 267G 142G 112G 56% / devtmpfs devtmpfs 32G 0 32G 0% /dev tmpfs tmpfs 32G 1.5M 32G 1% /dev/shm tmpfs tmpfs 32G 3.2G 29G 11% /run tmpfs tmpfs 32G 0 32G 0% /sys/fs/cgroup /dev/sda1 ext4 917G 532G 339G 62% /ssd2 /dev/sdc1 ext4 917G 589G 282G 68% /ssd /dev/sdb1 ext4 477M 103M 345M 24% /boot tmpfs tmpfs 6.3G 0 6.3G 0% /run/user/501 /dev/sdd1 ext4 60Z 60Z 0 100% /testfs [root@centos-master ~]# ll -h /ssd/bcdir/debug.log -rw------- 1 root root 1.2G 1月 19 2018 /ssd/bcdir/debug.log [root@centos-master ~]# cp /ssd/bcdir/debug.log /ssd2/
session2:执行iostat -d -x 1,-d表示监控磁盘设备的性能指标,-x表示Display extended statistics. 数字1表示,每秒生成1个报告。
[root@centos-master ~]# iostat -d -x 1 Linux 3.10.0-514.el7.x86_64 (centos-master) 2022年03月17日 _x86_64_ (24 CPU) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0.00 4.20 0.06 4.13 4.78 50.39 26.37 0.03 7.96 3.74 8.02 3.84 1.61 sdc 0.00 0.48 0.09 2.32 4.53 47.81 43.28 0.01 5.24 54.54 3.24 1.25 0.30 sdd 0.00 0.01 0.00 0.00 0.00 0.02 249.21 0.00 60.17 0.52 61.92 0.45 0.00 sda 0.00 0.00 0.13 0.06 15.99 7.10 243.94 0.00 12.45 0.97 36.75 0.32 0.01 dm-0 0.00 0.00 0.06 8.33 4.78 50.39 13.16 0.03 3.54 3.94 3.54 1.92 1.61 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 26.32 0.00 6.82 6.82 0.00 6.07 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0.00 0.00 12.00 7.00 360.00 56.00 43.79 0.12 6.32 4.25 9.86 4.26 8.10 sdc 0.00 0.00 51.00 0.00 6528.00 0.00 256.00 0.35 6.71 6.71 0.00 2.25 11.50 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 12.00 7.00 360.00 56.00 43.79 0.12 6.32 4.25 9.86 4.26 8.10 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0.00 0.00 1.00 3.00 4.00 12.00 8.00 0.03 6.75 7.00 6.67 6.75 2.70 sdc 0.00 0.00 739.00 0.00 94592.00 0.00 256.00 3.23 4.36 4.36 0.00 1.35 100.00 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 1.00 3.00 4.00 12.00 8.00 0.03 6.75 7.00 6.67 6.75 2.70 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0.00 0.00 0.00 3.00 0.00 12.00 8.00 0.03 11.00 0.00 11.00 11.00 3.30 sdc 0.00 0.00 711.00 0.00 91008.00 0.00 256.00 3.24 4.58 4.58 0.00 1.41 100.00 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 1.00 0.00 2764.00 0.00 353176.00 255.55 103.58 36.53 0.00 36.53 0.27 73.70 dm-0 0.00 0.00 0.00 3.00 0.00 12.00 8.00 0.03 11.00 0.00 11.00 11.00 3.30 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0.00 0.00 0.00 3.00 0.00 12.00 8.00 0.02 6.00 0.00 6.00 6.00 1.80 sdc 0.00 0.00 697.00 0.00 89216.00 0.00 256.00 3.26 4.68 4.68 0.00 1.44 100.10 sdd 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 0.00 0.00 3760.00 0.00 481280.00 256.00 141.60 37.63 0.00 37.63 0.27 100.10 dm-0 0.00 0.00 0.00 3.00 0.00 12.00 8.00 0.02 6.00 0.00 6.00 6.00 1.80 dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
可以观察到sdc设备的 r/s+w/s(该指标低,说明没有写请求) 开始比较高,说明正在从该设备读取文件,同时,它的%util也达到100%。另外,该设备的rkB/s +wkB/s也非常高。
渐渐的,看到sda设备的r/s +w/s ,以及rkB/s+wkB/s,%util变高。
这正好印证了从sdc设备拷贝文件到sda设备。
其中:
%util表示磁盘的使用率;
r/s +w/s表示磁盘的IOPS指标;
rkB/s+wkB/s表示磁盘的吞吐率throughout;
r_await+w_await 表示磁盘的延迟latency;
iostat -c选项也可以列出CPU使用率指标,具体可以man iostat查看。
2 pidstat -d -l 2
本来pidstat是查看进程性能指标的,加上-d表示查看进程的IO统计信息,-l列出进程执行的具体命令以及参数;数字2表示采样周期,每2秒一次输出。
我们先把文件系统的页缓存清掉,再将上述的cp文件操作重新执行一遍,并监测进程的IO指标。
session1:
[root@centos-master ~]# rm /ssd2/debug.log rm:是否删除普通文件 "/ssd2/debug.log"?y [root@centos-master ~]# free -m total used free shared buff/cache available Mem: 64383 38784 12849 12121 12749 12928 Swap: 0 0 0 [root@centos-master ~]# echo 1 >/proc/sys/vm/drop_caches [root@centos-master ~]# free -m total used free shared buff/cache available Mem: 64383 38783 12857 12121 12742 12932 Swap: 0 0 0 [root@centos-master ~]# cp /ssd/bcdir/debug.log /ssd2/
session2:
[root@centos-master ~]# pidstat -d -l 2 Linux 3.10.0-514.el7.x86_64 (centos-master) 2022年03月17日 _x86_64_ (24 CPU) 16时47分41秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 16时47分43秒 0 2119 62774.51 62431.37 0.00 cp -i /ssd/bcdir/debug.log /ssd2/ 16时47分43秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 16时47分45秒 0 1465 0.00 2.00 0.00 /opt/logstash-forwarder/bin/logstash-forwarder -config /etc/logstash-forwarder.conf 16时47分45秒 0 2119 99200.00 99200.00 0.00 cp -i /ssd/bcdir/debug.log /ssd2/ ... 16时47分49秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 16时47分51秒 0 563 0.00 46.00 0.00 jbd2/dm-0-8 16时47分51秒 0 2119 89856.00 89836.00 0.00 cp -i /ssd/bcdir/debug.log /ssd2/
其中pid=2119的进程就是session1的cp进程。
3 iotop观测磁盘IO
类似于top的工具。进入iotop之后,按键盘o,表示只查看活跃的IO信息,具体可以man iotop;
我们依然重复上述的操作,来检测:
session1:
[root@centos-master ~]# rm /ssd2/debug.log rm:是否删除普通文件 "/ssd2/debug.log"?y [root@centos-master ~]# echo 1 >/proc/sys/vm/drop_caches [root@centos-master ~]# cp /ssd/bcdir/debug.log /ssd2/
session2:
[root@centos-master ~]# iotop Total DISK READ : 92.57 M/s | Total DISK WRITE : 92.70 M/s Actual DISK READ: 94.12 M/s | Actual DISK WRITE: 164.69 M/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 2445 be/4 root 92.57 M/s 92.69 M/s 0.00 % 83.14 % cp -i /ssd/bcdir/debug.log /ssd2/ 7235 be/4 root 0.00 B/s 0.00 B/s 0.00 % 35.45 % [kworker/u65:0] 27009 be/4 etcd 0.00 B/s 3.53 K/s 0.00 % 0.55 % etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://0.0.0.0:2379 26612 be/4 etcd 0.00 B/s 3.53 K/s 0.00 % 0.29 % etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://0.0.0.0:2379 845 be/3 root 0.00 B/s 10.58 K/s 0.00 % 0.19 % [jbd2/sda1-8]
同样,可以看到对应的磁盘IO指标监测信息。