Linux IO磁盘篇整理小记

起源

本篇起源于对Kafka的一个问题排查,大致的原因是达到磁盘性能瓶颈。在追踪问题的时候用到iostat -x这命令,详细示例如下:

可以看到%idle(%idle小于70%说明IO压力已经比较大了)和%util的值都处于非正常状态。不过这里并不讲述Kafka的问题排查过程,反而是来讲述下IO指标的一些知识。每次遇到需要查看磁盘相关信息的时候,一些指标都会或多或少的遗忘,还要翻阅各种资料了解,故这里对相关的信息做一个相关的整理,在巩固相关知识点的同时也方便以后的查阅。

上面示例中的各个指标的含义分别为:
avg-cpu说明:
%user:在用户级别运行所使用的CPU的百分比。
%nice:带nice值(和进程优先级相关)的用户模式下运行所使用的CPU的百分比。
%system:在系统级别运行所使用CPU的百分比。
%iowait:CPU等待IO完成的时间百分比。(单个iowait指标值偏高并不能说明磁盘存在IO瓶颈,下面会有详述。)
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间的百分比。
%idle:CPU空闲时间的百分比。(idle值高,表示CPU较空闲。)
device说明:
rrqm/s:每秒进行merge的读操作数目。即:rmerge/s
wrqm/s:每秒进行merge的写操作数目。即:wmerge/s
r/s:每秒完成的读IO设备的次数。即rio/s
w/s:每秒完成的写IO设备的次数。即wio/s
rsec/s:每秒读扇区数。即rsect/s(每个扇区大小为512B。)
wsec/s:每秒写扇区数。即wsect/s
avgrq-sz:平均每次设备IO操作的数据大小(扇区);平均单次IO大小。
avgqu-sz:平均IO队列长度。
await:从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间;平均IO响应时间(毫秒)。
svctm:平均每次设备IO操作的服务时间(毫秒)。
%util:一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比。

正常情况下svctm应该是小于await值的,而svctm的大小和磁盘性能有关,CPU、内存的负荷也会对svctm值造成影响,过多的请求也会间接的导致svctm值的增加。await值的大小一般取决于svctm的值和IO队列的长度以及IO请求模式,如果scvtm比较接近await,说明IO几乎没有等待时间;如果await远大于svctm,说明IO请求队列太长,IO响应太慢,则需要进行必要优化。
如果%util接近100%,说明产生的IO请求太多,IO系统已经满负荷,该磁盘可能存在瓶颈。
队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 泛洪,如果avgqu-sz比较大,则说明有大量IO在等待。
(可以看完下面一节再来回顾这段内容。)

相关原理

对于await, svctm以及%util等,光从概念上来说,比较晦涩,可以通过下图的磁盘IO流程来加深理解:

(此图来源于遗产流....重新画了一遍)

磁盘IO场景

  1. 用户调用标准C库进行IO操作,数据流为:应用程序buffer->C库标准IObuffer->文件系统page cache->通过具体文件系统到磁盘。
  2. 用户调用文件IO,数据流为:应用程序buffer->文件系统page cache->通过具体文件系统到磁盘。
  3. 用户打开文件时使用O_DIRECT,绕过page cache直接读写磁盘。
  4. 用户使用类似dd工具,并使用direct参数,绕过系统cache与文件系统直接写磁盘。

发起IO请求请的步骤简析(以最长链路为例)
写操作:

  1. 用户调用fwrite把数据写C库标准IObuffer后就返回,即写操作通常是个异步操作。
  2. 数据到C库标准IObuffer后,不会立即刷新到磁盘,会将多次小数据量相邻写操作先缓存起来合并,最终调用write函数一次性写入(或者将大块数据分解多次write调用)page cache。
  3. 数据到page cache后也不会立即刷新到磁盘,内核有pdflush线程在不停的检测脏页,判断是否要写回到磁盘中,如果是则发起磁盘IO请求。
    读操作:
  4. 用户调用fread到C库标准IObuffer读取数据,如果成功则返回,否则继续。
  5. 到page cache读取数据,如果成功则返回,否则继续。
  6. 发起IO请求,读取到数据后缓存buffer和C库标准IObuffer并返回。可以看出,读操作是同步请求。

IO请求处理

  1. 通用块层根据IO请求构造一个或多个bio结构并提交给调度层。bio结构描述对一个磁盘扇区读/写操作。
  2. 调度器将bio结构进行排序和合并组织成队列且确保读写操作尽可能理想:将一个或多个进程的读操作合并到一起读,将一个或多个进程的写操作合并到一起写,尽可能变随机为顺序(因为随机读写比顺序读写要慢),读必须优先满足,而写也不能等太久。

IO调度算法
Linux的IO调度器有时也称之为磁盘调度器,工作机制是控制块设备的请求队列,确定队列中那些IO的优先级更高以及何时下发IO到块设备,以此来减少磁盘寻到时间,从而提高系统的吞吐量。
目前Linux共有如下几种IO调度算法:

  1. NOOP
    NOOP算法的全写为No Operation。该算法实现了最最简单的FIFO队列,所有IO请求大致按照先来后到的顺序进行操作。之所以说“大致”,原因是NOOP在FIFO的基础上还做了相邻IO请求的合并,并不是完完全全按照先进先出的规则满足IO请求。

假设有如下的io请求序列:
100,500,101,10,56,1000
NOOP将会按照如下顺序满足:
100(101),500,10,56,1000

2、CFQ
CFQ算法的全写为Completely Fair Queuing。该算法的特点是按照IO请求的地址进行排序,而不是按照先来后到的顺序来进行响应。
假设有如下的io请求序列:
100,500,101,10,56,1000
CFQ将会按照如下顺序满足:
100,101,500,1000,10,56
CFQ是默认的磁盘调度算法,对于通用服务器来说最好的选择。它视图均匀地分布对IO带宽的访问。CFQ为每个进程单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每个进程都能被很好的分配到IO带宽。IO调度器每次执行一个进程的4次请求。在传统的SAS盘上,磁盘寻道花去了绝大多数的IO响应时间。CFQ的出发点是对IO地址进行排序,以尽量少的磁盘旋转次数来满足尽可能多的IO请求。在CFQ算法下,SAS盘的吞吐量大大提高了。但是相比于NOOP的缺点是,先来的IO请求并不一定能被满足,可能会出现饿死的情况。

3、DEADLINE
DEADLINE在CFQ的基础上,解决了IO请求饿死的极端情况。除了CFQ本身具有的IO排序队列之外,DEADLINE额外分别为读IO和写IO提供了FIFO队列。读FIFO队列的最大等待时间为500ms,写FIFO队列的最大等待时间为5s。FIFO队列内的IO请求优先级要比CFQ队列中的高,而读FIFO队列的优先级又比写FIFO队列的优先级高。优先级可以表示如下:
FIFO(Read) > FIFO(Write) > CFQ

4、ANTICIPATORY
CFQ和DEADLINE考虑的焦点在于满足零散IO请求上。对于连续的IO请求,比如顺序读,并没有做优化。为了满足随机IO和顺序IO混合的场景,Linux还支持ANTICIPATORY调度算法。ANTICIPATORY的在DEADLINE的基础上,为每个读IO都设置了6ms的等待时间窗口。如果在这6ms内OS收到了相邻位置的读IO请求,就可以立即满足。 anticipatory 算法通过增加等待时间来获得更高的性能,假设一个块设备只有一个物理查找磁头(例如一个单独的SATA硬盘),将多个随机的小写入流合并成一个大写入流(相当于给随机读写变顺序读写),使用这个原理来使用读取写入的延时换取最大的读取写入吞吐量.适用于大多数环境,特别是读取写入较多的环境。

不同的磁盘调度算法(以及相应的IO优化手段)对Kafka这类依赖磁盘运转的应用的影响很大,建议根据不同的业务需求来测试选择合适的磁盘调度算法(以后的文章中会有相关的测试介绍)。
查看设备当前的IO调度器:cat /sys/block/{DEVICE-NAME}/queue/scheduler。其中{DEVICE-NAME}指的是磁盘设备的名称,即文章开头iostat -x中Device下方的vda,vdb等。
举例:

[root@hidden ~]# cat /sys/block/vda/queue/scheduler
noop anticipatory deadline [cfq]

修改当前的IO调度器: echo {SCHEDULER-NAME} > /sys/block/{DEVICE-NAME}/queue/scheduler。其中{SCHEDULER-NAME}取值为noop、anticipatory、deadline、cfq其中之一。
举例:

[root@hidden ~]# echo noop > /sys/block/vda/queue/scheduler
[root@hidden ~]# cat /sys/block/vda/queue/scheduler
[noop] anticipatory deadline cfq

以上设置重启之后会失效,如果要想重启后配置仍然生效,需要在内核启动参数中将elevator={SCHEDULER-NAME}写入/boot/grub/menu.lst文件中。在修改这个文件之前最好先备份一份,然后将elevator={SCHEDULER-NAME}添加到文件末尾即可。

巩固iowait

单独拎出iowait来说明是因为很多人对这个指标有一定的误区,包括笔者也经常把iowait和await混淆起来。顾名思义,就是系统因为io导致的进程wait。再深一点讲就是:这时候系统在做IO,导致没有进程在干活,cpu在执行idle进程空转,所以说iowait的产生要满足两个条件,一是进程在等IO,二是等IO时没有进程可运行。

常用的top命令中也有iowait的指标展示(%wa就是%iowait),示例如下:

对 iowait 常见的误解有两个:1. 误以为 iowait 表示CPU不能工作的时间;2. 误以为 iowait 表示I/O有瓶颈问题。iowait 的首要条件就是CPU空闲,既然空闲当然就可以接受运行任务,只是因为没有进程可以运行,CPU才进入空闲状态的。那为什么没有进程可以运行呢?因为进程都处于休眠状态、在等待某个特定事件:比如等待定时器、或者来自网络的数据、或者键盘输入、或者等待I/O操作完成,等等。iowait的升高并不能证明等待IO进程的数量增多了,也不能证明等待IO的总时间增加了。例如,在CPU繁忙期间发生的I/O,无论IO是多还是少,iowait都不会变;当CPU繁忙程度下降时,有一部分IO落入CPU空闲时间段内,导致iowait升高。再比如,IO的并发度低,iowait就高;IO的并发度高,iowait可能就比较低。所以iowait 所含的信息量非常少,它是一个非常模糊的指标,如果看到 iowait 升高,还需检查I/O量有没有明显增加,相应的一些指标有没有明显增大,应用有没有感觉变慢,如果都没有,就没什么好担心的。

Plus: 可以使用iotop命令来查找引起高iowait对应的进程。查看CPU使用率及负载的一些命令有:top、vmstat、mpstat、uptime等。



PS:消息中间件(Kafka、RabbitMQ)交流可加微信:hiddenzzh
欢迎支持笔者新书:《RabbitMQ实战指南》以及关注微信公众号:Kafka技术专栏。

时间: 2024-08-01 14:02:21

Linux IO磁盘篇整理小记的相关文章

linux没有磁盘碎片整理功能

  绝大多数的电脑用户都是在使用windows系统,我们都知道当电脑用起来很慢的时候,其中的一个办法就是磁盘碎片整理,但是在linux系统中,是没有磁盘碎片整理这项功能的,为什么linux中不需要磁盘碎片整理呢? 这是因为linux和windows的文件系统工作方式不同而造成的结果. 碎片整理就是通过移动文件来减少碎片的精密度,尽量让文件在硬盘中是连续存储的. windows系统的文件系统在保存文件时永远都会有碎片产生,而linux采取一种更智能的方式来放置文件,它将文件分散在整个磁盘,文件直接

Linux不需要磁盘碎片整理

Linux不需要磁盘碎片整理. 以下引自linux官方网站对碎片的解说:来源于 http://www.linux.org/docs/ldp/howto/Partition/appendix.html#fragmentation 引用: 10.4. Some facts about file systems and fragmentation Disk space is administered by the operating system in units of blocks and frag

为什么Linux不需要磁盘碎片整理

如果你是个Linux用户,你可能听说过不需要去对你的linux文件系统进行磁盘碎片整理.也许你注意到了,在Liunx安装发布包里没有磁盘碎片整理的工具.为什么会这样? https://dn-linuxcn.qbox.me/data/attachment/album/201206/14/103855laqzdm7q0d0s06es.png 为了理解为什么Linux文件系统不需要磁盘碎片整--而Windows却需要--你需要理解磁盘碎片产生的原理,以及Linux和Windows文件系统它们之间工作原

为什么 Linux 不需要碎片整理

翻译一篇小文章,练练英语翻译^_^本文原文地址:http://geekblog.oneandoneis2.org/index.php/2006/08/17/why_doesn_t_linux_need_defragmenting译者:jjmmma@gmail.com使用 Linux 的人经常会问这个问题:为什么 Linux 文件系统(filesystem)不需要碎片整理(defragment)? 以下我尝试用一个简单的,非技术的解答来会回答为什么有些文件系统会比另一些文件系统产生更多的碎片(fr

win7系统磁盘碎片整理方法

  大家在使用win7系统的过程之中会遇到很多关于系统的问题,这个时候各位就需要自己制定一个win7磁盘碎片整理的计划,这样才能保证系统的正常运行,首先各位需要根据这篇win7磁盘碎片整理的知识. Windows7自带的系统win7磁盘碎片整理软件对各位的系统维护的使用就已经足够了,相对来说,比一般的第三方软件虽然清理的不一定彻底,但是其功能更为保险,更适合各位的使用. 1.打开需要的系统盘,然后选择一个相关的需要进行win7磁盘碎片整理的盘,然后单机右键,打开属性,然后选择磁盘清理就可以了.

为什么Linux不需要碎片整理?

如果你是一个 Linux 用户,你可能会听说 Linux 的文件系统不需要碎片整理.你也可能会注意到 Linux 的发行版本也都没有磁盘碎片整理的功能.这是为什么呢? 要理解为什么 Linux 的文件系统不会像 Windows 的文件系统一样产生碎片,你首先要明白碎片到底是如何产生的,还有这两大操作系统的文件系统的工作方式到底有什么不同. 什么是磁盘碎片? 很多 Windows 的用户,甚至包括一些没有经验的用户,都相信定时整理文件系统中的碎片会让他们的电脑运行得更快.但他们都不知道这是为什么.

如何快速格式化和磁盘碎片整理

快速格式化 所谓的快速格式化,在格式化过程中重写引导记录,不检测磁盘坏簇,FAT表中除坏簇以外所有表项清零,根目录表清空,数据区不变.而正常格式化会重写 引导记录,重新检查标记坏簇,其余表项清零,清空根目录表,对数据区清零.快速格式化后的硬盘,可以通过技术手段进行恢复. Dos下的format命令是用来进行格式化的. FORMAT A:或c:, d:等等,后面可以加一些参数 比如FORMAT A: /S 这是格式化并追加系统.也就是制作一个简单的启动盘. 如果给硬盘进行格式化(重装系统前的准备工

加快磁盘碎片整理速度的技巧

本文介绍可以帮助我们加快系统整理磁盘碎片速度的几个技巧. 关闭应用程序 由于某些程序在运行的过程中可能需要反复地读取硬盘中的数据,这会影响碎片整理程序的正常工作,在系统不稳定的情况下甚至还会导致死机现象的发生.因此,为了加快磁盘碎片的整理速度,最好把各个正在运行的程序关闭掉. 调整参数或使用专用软件 如果硬盘的容量或者分区的容量比较小,对其进行碎片整理工作需要的时间不会太长,但对于一些塞 满数据的大硬盘和分区来说,则需要一个漫长的等待过程.所以,我们在整理这些大容量的硬盘或者分区时,可以采取下面

Defrag磁盘碎片整理命令使用说明

defrag:磁盘碎片整理 [适用场合]磁盘读写次数很多,或磁盘使用时间很长了,可能需要使用这条命令 整理磁盘.磁盘碎片并不是指磁盘坏了,而只是由于多次的拷贝和删 除文件后,磁盘使用会很不连贯,致使速度变慢. 本文发表于http://bianceng.cn(学电脑) [用法] 1. C:\>defrag 2. 选择要整理的磁盘 3. 电脑分析磁盘状况,然后告诉我们磁盘有多少需整理.按Esc键 4. 选择Optimization Method(磁盘优化方法),选择"全部优化" 或&