在Linux性能调优这一个系列中,前几篇文章主要介绍了内存的相关知识以及如何调优,下面几篇主要谈一下磁盘IO性能的各个方面。
1、文件系统和磁盘
在分析IO性能之前,我们要先了解一下文件系统和磁盘的知识。
在Linux领域有一句非常著名的名言叫做:“一切皆文件”。不管是我们运行的应用,还是Linux系统本身,亦或者底层运行的内核程序都要通过统一的文件系统进行管理。既然是文件,它们是怎么存储管理呢?
这里要提两个重要的概念 目录项和索引节点(inodes)
,而且这两者有着非常紧密的关系。因为一切皆文件,所以每个文件的存放都要有一个索引来记录元数据,并且是一一对应。索引本身也是文件,也要放到磁盘空间里。目录项更像是树状结构,里面有一个索引指针,关联着索引节点,而且目录项可以包含好几个索引指针,当然也就对应多个索引节点。
目录项本身是不存储到磁盘上的,在系统启动后,会自动加载到内核缓存中,也就是目录项缓存。在前面我们讲内存时,提到内核中有个slab,其实slab缓存就是存目录项和索引缓存的。
索引节点对应的文件就是我们存储的大量数据了,它要存储到磁盘的逻辑块中,而逻辑块就是由物理磁盘扇区组成了。同样,索引节点的数据放到磁盘的索引分区内。
当前这里还有一个重要知识点要提及,就是在系统启动时,会首先去加载一个叫超级块的区域,它存放了整个系统能够运行的基础信息,例如系统是否完整、空间信息怎么样、设置的一些策略等。它是跟索引分区和数据存储逻辑块并列存在的。
2、虚拟文件系统
在Linux发展过程中,出现了很多不同的文件系统标准,例如ext4、xfs等,他们所提供的接口是不同的,对应上层业务来说去一一分辨太过于麻烦。虚拟文件系统的出现,可以兼容所有可用的文件系统,使得用户的应用程序只调用虚拟文件系统的标准接口即可。在Linux系统内部,虚拟文件系统是不需要磁盘去存储的,他们会在系统启动时,自动加载到内存缓存中,例如/proc/
、 /sys/ 这些目录都是。
为了更容易理解,我们举个例子,有一块磁盘/dev/sdb1,首先格式化成ext4的文件系统标准,然后还要mount到一个挂载点/mnt,最后通过虚拟文件系统命令(cat、touch、rm等)去操作,这样才能正常读取数据。
你可能会问,是不是可以不用这一套虚拟文件系统,当然可以,一般高性能存储,都是直接裸盘使用,直接将盘对接到存储应用系统的,目的就是获取更高的性能,省去操作系统的虚拟文件系统机制。
用AI工具生产了下面这个图,可以帮助理解一下。

3、磁盘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操作时,没有响应就停止,不再执行其他任务。非阻塞则不管有没有响应都继续执行其他任务,没有响应的通过轮询是否调用完成。而对于是否等待响应结果,则可分为同步和异步。同步是应用等待结果后再继续执行,异步则不等待继续执行,只是通过事件的形式通知应用程序。
4、一些观察工具
以下工具都是前几篇介绍过的工具,可以在 ** 最下面链接查看 ** 。
** df -i ** #可以看到索引数据inodes
root@i-6f6q3whn:~# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 30916899 564 30916335 1% /dev
tmpfs 30928195 783 30927412 1% /run
/dev/vda2 13107200 116799 12990401 1% /
tmpfs 30928195 1 30928194 1% /dev/shm
tmpfs 30928195 3 30928192 1% /run/lock
tmpfs 30928195 18 30928177 1% /sys/fs/cgroup
cat /proc/meminfo #可以查看页缓存和可回收 Slab 缓存
root@i-6f6q3whn:~# cat /proc/meminfo | grep -E "SReclaimable|Cached"
Cached: 748316 kB
SwapCached: 0 kB
SReclaimable: 179508 kB
cat /proc/slabinfo #可以从这里看到目录项和索引节点缓存
root@i-6f6q3whn:~# 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>
btrfs_inode 0 0 1168 28 8 : tunables 0 0 0 : slabdata 0 0 0
mqueue_inode_cache 34 34 960 34 8 : tunables 0 0 0 : slabdata 1 1 0
fuse_inode 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0
ecryptfs_inode_cache 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
fat_inode_cache 0 0 744 44 8 : tunables 0 0 0 : slabdata 0 0 0
squashfs_inode_cache 2579 3726 704 46 8 : tunables 0 0 0 : slabdata 81 81 0
ext4_inode_cache 73924 80011 1096 29 8 : tunables 0 0 0 : slabdata 2759 2759 0
hugetlbfs_inode_cache 102 102 632 51 8 : tunables 0 0 0 : slabdata 2 2 0
sock_inode_cache 20631 20631 832 39 8 : tunables 0 0 0 : slabdata 529 529 0
proc_inode_cache 87537 90432 680 48 8 : tunables 0 0 0 : slabdata 1884 1884 0
shmem_inode_cache 10120 10485 720 45 8 : tunables 0 0 0 : slabdata 233 233 0
inode_cache 63017 64448 608 53 8 : tunables 0 0 0 : slabdata 1216 1216 0
dentry 272199 298956 192 42 2 : tunables 0 0 0 : slabdata 7118 7118 0
其中dentry 就是 目录项缓存 。
970

被折叠的 条评论
为什么被折叠?



