【精品】I/O性能优化——这一篇就足够啦

背景

        继上一篇CPU性能优化文章 ,本次向大家分享关于I/O性能优化的分析套路以及常见措施。后续还有关于内存及网络优化的篇章。

基本概念

        对于I/O我们先了解几个概念,文件系统,磁盘,文件

磁盘

        磁盘为系统提供了最基本的持久化存储能力。

磁盘的分类

        根据存储介质的不同,磁盘可以分为两类:机械磁盘和固态磁盘。

机械磁盘:由盘片读写磁头组成。数据就存储在盘片的环状磁道中。当读写数据时,需要先将读写磁头移动到所在的磁道,然后才能访问数据

固态磁盘:由固态电子元器件组成,固态硬盘不需要磁道寻址。

由上可知

  1. 机械磁盘当访问的数据不连续时,就会消耗寻道时间,降低效率;而固态磁盘则不会。

  2. 无论是机械磁盘还是固态磁盘,连续IO要比随机IO快。

    1. 通用块层策略,可以将连续的IO请求合并,提高效率。

    2. 利用文件系统的缓存机制。

性能指标

磁盘性能的衡量标准,必须要提到五个常见指标。

  • 使用率。指磁盘处理I/O的时间百分比。注,使用率100%,磁盘仍可能可以接受新的IO请求。

  • 饱和度。指磁盘处理I/O的繁忙程度。注,当饱和度100%,磁盘不能接受新的IO请求。

  • IOPS(Input/Output Per Second)。每秒的IO请求数。

  • 吞吐量。指每秒的IO请求大小

  • 响应时间。指IO请求发出,到响应的时间间隔。

查看性能指标方式

yihua@ubuntu:~$ iostat -d -x 1
Linux 4.15.0-213-generic (ubuntu)       10/30/2023      _x86_64_        (4 CPU)
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.01      0.00     0.00     0.00   0.00   0.00    0.50    0.00   0.00     1.85     0.00   0.02   0.00
loop1            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.06    0.00   0.00     4.08     0.00   0.00   0.00
loop2            0.00    0.00      0.01      0.00     0.00     0.00   0.00   0.00    0.33    0.00   0.00     2.11     0.00   0.01   0.00
loop3            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00   10.22    0.00   0.00     2.50     0.00   0.00   0.00
loop4            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.06    0.00   0.00     4.09     0.00   0.07   0.00
loop5            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    2.57    0.00   0.00     2.57     0.00   0.00   0.00
loop6            0.05    0.00      0.05      0.00     0.00     0.00   0.00   0.00    2.69    0.00   0.00     1.06     0.00   0.05   0.00
loop7            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.20    0.00   0.00     2.25     0.00   0.03   0.00
sda              0.38    0.61     11.59     44.20     0.07     0.63  15.21  50.81    0.81    4.16   0.00    30.82    72.85   0.25   0.02
scd0             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.08    0.00   0.00     3.75     0.00   0.08   0.00
scd1             0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.13    0.00   0.00    17.48     0.00   0.13   0.00
loop8            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00   10.22    0.00   0.00     2.50     0.00   0.00   0.00
loop9            0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.75    0.00   0.00     3.19     0.00   0.02   0.00
loop10           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00   11.20    0.00   0.00     2.35     0.00   0.00   0.00
loop11           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.88    0.00   0.00     3.41     0.00   0.06   0.00
loop12           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    4.63    0.00   0.00     2.47     0.00   0.00   0.00
loop13           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.23    0.00   0.00     4.51     0.00   0.08   0.00
loop14           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    2.37    0.00   0.00     3.23     0.00   0.44   0.00
loop15           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.68    0.00   0.00     3.39     0.00   0.06   0.00
loop16           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.58    0.00   0.00     4.61     0.00   0.19   0.00
loop17           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.80    0.00   0.00     2.23     0.00   0.08   0.00
loop18           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00   27.00    0.00   0.00     1.00     0.00   0.00   0.00
loop19           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.96    0.00   0.00     2.19     0.00   0.07   0.00
loop20           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    2.82    0.00   0.00     2.41     0.00   0.00   0.00
loop21           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    1.43    0.00   0.00     4.57     0.00   0.07   0.00
loop22           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    2.18    0.00   0.00     2.97     0.00   0.37   0.00
loop23           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.56    0.00   0.00     2.17     0.00   0.03   0.00
loop24           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    5.91    0.00   0.00     2.57     0.00   0.00   0.00
loop25           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.37    0.00   0.00     2.91     0.00   0.02   0.00
loop26           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    5.80    0.00   0.00     2.35     0.00   0.00   0.00
loop27           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     1.60     0.00   0.00   0.00

文件系统

文件系统是在磁盘的基础上,提供了一个用来管理文件的树状结构。其本身就是对存储设备上的文件进行组织管理的机制。组织方式不同,就会形成不同的文件系统。

文件

        为了方便管理,文件系统会为文件分配两个数据结构。索引节点目录结构

  • 索引节点。简称inode,用来记录文件的元数据,比如inode编号,文件大小,访问权限,修改日期,数据位置等。索引节点和文件一一对应,它跟文件内容一样,都会被持久化存储到磁盘中。所以索引节点会占用磁盘空间

  • 目录项。简称dentry,用来记录文件的名字,索引节点指针以及其他目录项的关联关系。多个关联目录项,就构成了文件系统的目录结构。

由上可知:

  1. 索引节点和目录项也是占用磁盘空间的。并且文件系统中的索引节点和目录项是有上限个数的。因此当linux 系统中若存在大量的小文件。可能磁盘空间还有空余,但是已经无法再创建新文件了。

  2. 目录项和索引节点的关系是多对一。即一个文件可以有多个别名,比如linux 系统中的硬链接。

文件I/O

        根据访问文件的方式不同,导致I/O的分类有多种,常见的有以下四种。

  • 缓存IO/非缓存IO。这里的缓存指的是应用层缓存,因为有些标准库会具有缓存机制,减少IO操作次数。比如printf遇到换行符才会输出,这就是因为换行符之前的内容被标准库缓存了,此时的内容还在应用层,没有到内核。

  • 直接IO/非直接IO。文件系统为了加快数据读写操作,会将数据进行缓存,根据特定的机制(缓存满、系统调用、缓存过期、磁盘写入请求或缓存刷新)将缓存写入磁盘,这就是我常说的落盘机制。直接IO则是在系统调用阶段指定O_DIRECT标识,表示不适用文件系统的缓存机制。

  • 阻塞IO/非阻塞IO。指应用程序执行系统调用后,如果没有获取结果,是否阻塞当前线程。比如在访问管道或网络套接字时,设置O_NONBLOCK标识,就表示用非阻塞方式访问。

  • 同步IO/异步IO。指应用程序执行IO操作后,是否需要等待IO完成或响应。比如在操作文件时,如果你设置了O_DSYNC,就要等待文件数据写入磁盘后,才能返回。

上述描述中,缓存IO和直接IO比较好理解和区分。但是对于阻塞IO 和 同步IO 如何区分呢?

我的理解是:

  1. 阻塞IO,是应用程序主动的行为。它会主动释放持有的资源,CPU或文件描述符。

  2. 同步IO,是应用程序被动的行为。它一直等待事件满足,在等待过程中不会释放资源。

性能分析

        关于文件系统,我们一般在意两个性能参数。容量缓存

  • 容量

        通过df命令可以查看当前文件系统剩余大小。

yihua@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           392M  3.6M  389M   1% /run
/dev/sda1        49G   42G  4.5G  91% /
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/loop1      219M  219M     0 100% /snap/gnome-3-34-1804/93
/dev/loop3      512K  512K     0 100% /snap/gnome-characters/789
/dev/loop2       82M   82M     0 100% /snap/gtk-common-themes/1534
/dev/loop16     106M  106M     0 100% /snap/core/15925
/dev/loop5      1.5M  1.5M     0 100% /snap/gnome-system-monitor/184
/dev/loop10     896K  896K     0 100% /snap/gnome-logs/121
/dev/loop11     141M  141M     0 100% /snap/gnome-3-26-1604/111
/dev/loop12     2.3M  2.3M     0 100% /snap/gnome-calculator/953
/dev/loop8      512K  512K     0 100% /snap/gnome-characters/795
/dev/loop13      74M   74M     0 100% /snap/core22/858
/dev/loop18     128K  128K     0 100% /snap/bare/5
/dev/loop14     350M  350M     0 100% /snap/gnome-3-38-2004/143
/dev/loop19      64M   64M     0 100% /snap/core20/2015
/dev/loop23      64M   64M     0 100% /snap/core20/1974
/dev/loop20     2.2M  2.2M     0 100% /snap/gnome-calculator/950
/dev/loop24     1.7M  1.7M     0 100% /snap/gnome-system-monitor/186
/dev/loop21      74M   74M     0 100% /snap/core22/864
/dev/loop7       56M   56M     0 100% /snap/core18/2790
/dev/loop26     896K  896K     0 100% /snap/gnome-logs/119
/dev/loop25     486M  486M     0 100% /snap/gnome-42-2204/126
/dev/loop15     141M  141M     0 100% /snap/gnome-3-26-1604/104
/dev/loop0       92M   92M     0 100% /snap/gtk-common-themes/1535
/dev/loop4      219M  219M     0 100% /snap/gnome-3-34-1804/90
/dev/loop6      106M  106M     0 100% /snap/core/16202
/dev/loop9      350M  350M     0 100% /snap/gnome-3-38-2004/140
/dev/loop22     497M  497M     0 100% /snap/gnome-42-2204/141
tmpfs           392M   28K  392M   1% /run/user/121
tmpfs           392M   36K  392M   1% /run/user/1000
/dev/sr1        1.9G  1.9G     0 100% /media/yihua/Ubuntu 18.04.1 LTS amd64
/dev/sr0         46M   46M     0 100% /media/yihua/CDROM
/dev/loop27      56M   56M     0 100% /snap/core18/2796

注: 文件系统显示的大小并不等于磁盘的大小。

  • 缓存

我们可以通过free命令查看当前缓存大小。

yihua@ubuntu:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           3.8G        1.3G        1.5G         31M        1.1G        2.3G
Swap:          2.0G         87M        1.9G

但是我们文件系统中主要有三类缓存,页缓存,索引节点缓存,目录项缓存。这些参数无法直接从free命令中获取。因此,需要从/proc/meminfo中获取详情。

yihua@ubuntu:~$ cat //proc/meminfo
MemTotal:        4013248 kB
MemFree:         1576180 kB
MemAvailable:    2400348 kB
Buffers:           97364 kB
Cached:           906452 kB
SwapCached:         3840 kB
Active:           795076 kB
Inactive:        1181056 kB
Active(anon):     376460 kB
Inactive(anon):   628448 kB

其中Cached就是三者缓存和,可以通过slabtop查看更细节内容

 Active / Total Objects (% used)    : 989070 / 1045443 (94.6%)
 Active / Total Slabs (% used)      : 20382 / 20382 (100.0%)
 Active / Total Caches (% used)     : 84 / 114 (73.7%)
 Active / Total Size (% used)       : 242473.95K / 262634.13K (92.3%)
 Minimum / Average / Maximum Object : 0.01K / 0.25K / 8.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
 51145  47067   0%    0.60K    965       53     30880K inode_cache
 56192  55803   0%    0.50K    878       64     28096K kmalloc-512
145020 144307   0%    0.13K   2417       60     19336K kernfs_node_cache
 17168  13103   0%    1.07K    592       29     18944K ext4_inode_cache
 93870  76404   0%    0.19K   2235       42     17880K dentry
 29792  21524   0%    0.57K    532       56     17024K radix_tree_node

        由上可知,目录项和索引节点缓存约占32M。

I/O栈

虚拟文件系统

        根据上图可知,为了支持不同的文件系统,linux内核在用户空间和文件系统之间,又引入了一个抽象层,也就是虚拟文件系统VFS(Virtual File System)。

        VFS定义了所有文件系统都支持的数据结构和标准接口。这样用户进程就不需要和内核中的其他子系统,只需要跟 VFS 提供的统一接口进行交互就可以了,而不需要再关心底层各种文件系统的实现细节。

在 VFS 的下方,Linux 支持各种各样的文件系统。按照存储位置的不同,这些文件系统可以分为三类。

  • 第一类是基于磁盘的文件系统,也就是把数据直接存储在计算机本地挂载的磁盘中。常见的 Ext4、XFS、OverlayFS 等,都是这类文件系统。

  • 第二类是基于内存的文件系统,也就是我们常说的虚拟文件系统。这类文件系统,不需要任何磁盘分配存储空间,但会占用内存。我们经常用到的 /proc 文件系统,其实就是一种最常见的虚拟文件系统。此外,/sys 文件系统也属于这一类,主要向用户空间导出层次化的内核对象

  • 第三类是网络文件系统,也就是用来访问其他计算机数据的文件系统,比如 NFS、SMB、iSCSI 等。

        这些文件系统,要先挂载到 VFS 目录树中的某个子目录(称为挂载点),然后才能访问其中的文件。

通用块层

        与虚拟文件系统 VFS 类似,为了减小不同块设备的差异带来的影响,Linux 通过一个统一的通用块层,来管理各种不同的块设备。

通用块层处于文件系统和磁盘驱动中间的一个块设备抽象层。它主要有两个功能:

  1. 向上,为文件系统和应用程序提供访问块设备的标准接口;向下,把各种异构的磁盘设备抽象为统一的块设备,并提供统一框架来管理这些设备的驱动程序。

  2. 块设备还会将发送过来的I/O请求排队,并通过重新排序,请求合并等方式,提高磁盘的效率。

其中排序的算法有四种,如下:

  • NONE。不做任何处理。

  • NOOP。实际上是一个先进先出的队列,在此基础上做最基本的请求合并。

  • CFQ。完全公平调度器,现在很多发行版默认的I/O调度策略。它为每一个进程维护了一个I/O队列,并按照时间片均匀分布每个进程的I/O请求。

  • DeadLine。分别为读、写请求创建了不同的 I/O 队列,可以提高机械磁盘的吞吐量,并确保达到最终期限(deadline)的请求被优先处理。多用在 I/O 压力比较重的场景,比如数据库等。

工具介绍

          在进行IO性能分析的过程中,我们需要用到一些工具,协助我们分析,定位,解决问题。

top

    top 命令是我们在分析性能问题时,常用到的一个工具。执行top -d 1 ,-d 参数表示更新频率。默认3s。

yihua@ubuntu:~$ top -d 1
top - 23:36:05 up 22:14,  4 users,  load average: 0.48, 0.10, 0.03
Tasks: 330 total,   1 running, 253 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9.9 us, 66.5 sy,  0.0 ni, 23.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4013240 total,  1004708 free,  1293040 used,  1715492 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  2398648 avail Mem
 Unknown command - try 'h' for help
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 10612 yihua     20   0  120024   7940   6636 S 305.0  0.2   0:21.79 sysbench
 10623 yihua     20   0   44380   4132   3328 R   1.0  0.1   0:00.03 top
     1 root      20   0  225544   9332   6636 S   0.0  0.2   0:03.29 systemd
     2 root      20   0       0      0      0 S   0.0  0.0   0:00.04 kthreadd
     4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
     6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq
     7 root      20   0       0      0      0 S   0.0  0.0   0:00.09 ksoftirqd/0
     8 root      20   0       0      0      0 I   0.0  0.0   0:00.61 rcu_sched
     9 root      20   0       0      0      0 I   0.0  0.0   0:00.00 rcu_bh
    10 root      rt   0       0      0      0 S   0.0  0.0   0:00.00 migration/0
    11 root      rt   0       0      0      0 S   0.0  0.0   0:00.09 watchdog/0

第三行:%Cpu(s): 9.9 us, 66.5 sy, 0.0 ni, 23.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

表示当前CPU的资源消耗状态。参数可参考一下。

user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。即执行用户态代码

nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。执行用户态代码

system(通常缩写为 sys),代表内核态 CPU 时间。执行内核态代码

idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。

iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。进程不可中断状态持续时间

irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。执行硬中断代码

softirq(通常缩写为 si),代表处理软中断的 CPU 时间。执行软中断代码

steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。

通过top 命令,我们可以确认当前系统是否出现了IO 性能问题。

iostat

    iostat可以查看系统中所有文件系统的状态。

# -d表示显示I/O性能指标,-x表示显示扩展统计(即所有I/O指标) 
$ iostat -x -d 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.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 
sdb              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   0.00   0.00 
sda              0.00   64.00      0.00  32768.00     0.00     0.00   0.00   0.00    0.00 7270.44 1102.18     0.00   512.00  15.50  99.20

        在磁盘性能指标章节中,衡量磁盘性能指标有使用率,饱和度,IOPS,吞吐量,响应时间。对应关系为

  • 使用率 (%util)

  • 饱和度,饱和度通常也没有其他简单的观测方法

  • IOPS (r/s + w/s)

  • 吞吐量(rkB/s + wkB/s)

  • 响应时间(r_await + w_await)

        由上可知,当前sda 磁盘出现了性能瓶颈,主要是体现在 使用率高,写请求响应需要7秒。

由上可知,通过iostat 可以快速定位到当前是哪一个磁盘出现了IO性能瓶颈,以及确认是哪一类I/O操作出现了瓶颈。

pidstat

pidstat 可以帮助我们观察进程的IO状态。

$ pidstat -d 1 
13:39:51      UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command 
13:39:52      102       916      0.00      4.00      0.00       0  rsyslogd

从 pidstat 的输出你能看到,它可以实时查看每个进程的 I/O 情况,包括下面这些内容。

  • 用户 ID(UID)和进程 ID(PID) 。每秒读取的数据大小(kB_rd/s) ,单位是 KB。

  • 每秒发出的写请求数据大小(kB_wr/s) ,单位是 KB。

  • 每秒取消的写请求数据大小(kB_ccwr/s) ,单位是 KB。

  • 块 I/O 延迟(iodelay),包括等待同步块 I/O 和换入块 I/O 结束的时间,单位是时钟周期。

由上可知,通过pidstate 我们可以定位到哪一个进程导致了IO负载较高。

strace

strace命令可以查看进程的系统调用。通过I/O栈可知,应用程序必须通过系统调用才可以进入内核态,进行I/O请求。

$ strace -f -p 18940 
strace: Process 18940 attached 
...
mmap(NULL, 314576896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0f7aee9000 
mmap(NULL, 314576896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0f682e8000 
write(3, "2018-12-05 15:23:01,709 - __main"..., 314572844 
) = 314572844 
munmap(0x7f0f682e8000, 314576896)       = 0 
write(3, "\n", 1)                       = 1 
munmap(0x7f0f7aee9000, 314576896)       = 0 
close(3)                                = 0 
stat("/tmp/logtest.txt.1", {st_mode=S_IFREG|0644, st_size=943718535, ...}) = 0 

通过strace输出,可以确定,当前I/O操作,主要是write操作,并且对应的文件套接字是3。

由上可知,strace 命令可以观察到进程的系统调用及其关联的文件套接字

lsof

lsof它专门用来查看进程打开文件列表,不过,这里的“文件”不只有普通文件,还包括了目录、块设备、动态库、网络套接字等。

$ lsof -p 18940 
COMMAND   PID USER   FD   TYPE DEVICE  SIZE/OFF    NODE NAME 
python  18940 root  cwd    DIR   0,50      4096 1549389 / 
python  18940 root  rtd    DIR   0,50      4096 1549389 / 
… 
python  18940 root    2u   CHR  136,0       0t0       3 /dev/pts/0 
python  18940 root    3w   REG    8,1 117944320     303 /tmp/logtest.txt 

        由上可知,文件套接字3,对应的是/tmp/logtest.txt文件,这样就可以确定相应代码块了。

I/O性能优化套路

 通过iostat查看系统磁盘的I/O状态。若出现IO性能瓶颈,正常会出现响应时间比较高。

  1.  若存在吞吐量,IOPS,使用率比较高,则说明存在进程进行IO操作导致的
    1.  通过pidstat可以快速定位到是哪一个进程进行IO操作。
      1. 若是内核进程。一般是外部环境导致,比如外部设备交互频繁,网络环境异常。

      2. 若是应用进程。通过strace + lsof 确认当前进程在做什么。

        1. 若是正在进行网络通信,则分析网络环境。

        2. 进行文件操作或操作磁盘。则分析应用程序。

  2. 若仅是响应时间比较高,但是吞吐量,IOPS,使用率正常,则有可能是内存导致的,因为内存不足时,也会导致IO响应delay。

    1. 通过vmstate +/proc/meminfo分析是哪一缓存出现异常。根据情况进行处理。

常见优化措施

应用层优化

  1. 用追加写替代随机写,减少寻址开销

  2. 借助缓存I/O,充分利用系统缓存,降低实际I/O的次数。比如打开文件不使用O_DIRECT 参数。

  3. 创建应用程序缓存,类似Redis这类外部缓存系统,比如C标准库提供了fopen,fread等库函数,都会利用标准库的缓存,减少磁盘操作。

  4. 频繁读写时,可以用mmap替代read/write,减少内存拷贝次数。

  5. 尽量将写请求合并,而不是将每一个请求同步写入磁盘,既可以用fsync(),取代O_SYNC。

  6. 根据业务场景的需求,设置IO调度算法。若是CFQ算法,可以设置应用程序的优先级。

文件系统优化

  1. 根据负载不同,选择最适合的文件系统。比如相比于 ext4 ,xfs 支持更大的磁盘分区和更大的文件数量,如 xfs 支持大于 16TB 的磁盘。但是 xfs 文件系统的缺点在于无法收缩,而 ext4 则可以。

  2. 优化文件系统的缓存。

  3. 在不需要持久化时,还可以使用内存文件系统tmpfs

磁盘优化

  1. 换性能更好的磁盘。比如用SDD 替换HDD。

  2. 对应用程序的数据,进行磁盘级别的隔离。比如日志和数据库程序,都需要进行频繁的读写操作。我们可以单独配置磁盘。

  3. 在顺序读比较多的场景中,我们可以增大磁盘的预读数据。调整内核选项 /sys/block/sdb/queue/read_ahead_kb,默认大小是 128 KB,单位为 KB。

  4. 优化内核块设备I/O的选项。比如调整磁盘队列的长度。/sys/block/sdb/queue/nr_requests,适当增大队列长度,可以提升磁盘的吞吐量。

  5. dmesg 查看是否有硬件I/O故障的日志。

总结

        以上便是我总结,若有好的想法或案例,欢迎各位同学分享,补充。

 若我的内容对您有所帮助,还请关注我的公众号。不定期分享干活,剖析案例,也可以一起讨论分享。
我的宗旨:
踩完您工作中的所有坑并分享给您,让你的工作无bug,人生尽是坦途

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢艺华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值