磁盘I/O流程

FIFO (Read) > FIFO (Write) > CFQ 从编程角度而已,一般磁盘I/O的场景有以下四种:

(1)用户调用标准C库进行I/O操作,数据流为:应用程序buffer->C库标准IObuffer->文件系统页缓存->通过具体文件系统到磁盘

(2)用户调用文件I/O,数据流问:应用程序buffer->文件系统页缓存->通过具体文件系统到磁盘

(3)用户打开文件时使用O_DIRECT,绕开页缓存直接读写磁盘

(4)用户使用类似dd工具,并使用direct参数,绕过系统cache与文件系统直接写磁盘。

发起I/O请求的步骤可以表述为如下的内容(以最长链路为例)

写操作:用户调用fwrite把数据写入C库标准IObuffer后就返回,即写操作通常是异步操作;

数据写入C库标准IObuffer后,不会立即刷新到磁盘,会将多次小数据量相邻写操作先缓存起来合并,最终调用write函数一次写入(或者将大块数据分解多次write调用)页缓存;数据到达页缓存后也不会立即刷新到磁盘,内核有pdflush线程在不停地检测脏页,判断是否要写回到磁盘,如果是则发起磁盘I/O请求。

读操作:用户调用fread到C库标准IObuffer中读取数据,如果成功则返回,否则继续;发起I/O请求,读取数据后缓存buffer和C库标准IObuffer并返回。可以看出,读操作是同步请求。

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

磁盘I/O流程_第1张图片

 针对不同的应用场景,I/O调度处理也会影响I/O的读写性能,目前linux系统中的I/O调度策略有4种,分布是NOOP、CFQ、DEADLINE和ANTICIPATORY,默认为CFQ。

1.NOOP

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

假设有如下的I/O请求序列:

100,500,101,10,56,1000

NOOP将会按照如下顺序满足I/O请求:

100(101),500,10,56,1000

2.CFQ

CFQ算法的全写为Completely Fair Queuing。该算法的特定是按照I/O请求的地址进行排序,而不是按照先来后到的顺序进行响应。

假设有如下的I/O请求序列:

100,500,101,10,56,1000

CFQ将会按照如下顺序满足:

100, 101,500,1000,10,56

CFQ是默认的磁盘调度算法,对于通用服务器来说是最好的选择。它试图均匀地分布对I/O带宽的访问。CFQ为每个进程单独创建一个队列来管理该进程所产生的请求,也就是说,每个进程一个队列,各队列之间的调度使用时间片段进行调度,以此来保证每个进程都能被很好第分配到I/O带宽。I/O调度器每次执行一个进程的4次请求。在传统的SAS盘上,磁盘寻道花去了绝大多数的I/O响应时间。CFQ的出发点是对I/O地址进行排序,以尽量少的磁盘旋转次数来满足尽可能多的I/O请求。在CFQ算法下,SAS盘的吞吐量大大提高了。相比于NOOP的缺点是,先来的I/O请求并不一定能被满足,可能会出现“饿死”的情况。

3.DEADLINE

DEADLINE在 CFQ 的基础上,解决了 I /0 请求“饿死”的极端情况。除了 CFQ 本身具有 I/0 排序队列, DEADLINE 额外分别为读 I/O 和写I /0 提供了 FIFO 队列。读 FIFO 队列的最
大等待时间为 500ms ,写 FIFO 队列的最大等待时间为5 s。  FIFO 队列内的I/O 请求优先级要比
CFQ 队列中的高,而读 FIFO 队列的优先级又比写 FIFO 队列的优先级高。优先级可以表示如下
FIFO (Read) > FIFO (Writ e) > CFQ
4、ANTICIPATORY
CFQ和 DEADLINE 考虑的焦点在于满足零散 I/O 请求上 对于连续的 I/O 请求,比如顺序读
并没有做优化,  为了满足随机 I/O 和顺序I/O 混合的场, Linux 还支持 ANTICIPATORY
调度算法。  ANTICIPATORY在 DEADLINE 的基础上,为每个读 I/O 都设置了 6ms 的等待时间
窗口。 如果在 6ms内 OS 收到了相邻位置的读 I/O 请求,就可以立即满足。 ANTICIPATORY 算
法通过增加等待时间来获得更高的性能,假设一 个块设备只有一 个物理查找磁头(例如 1  个单
独的 SATA 硬盘),将多个随机的小写入流合并成 个大写入流(相当于将随机读写变顺序读
写),通 过这个原 理来使用读取/写入的延时换取最大的读取/写入吞 量。适用于大多数环境
特别是读取/写入较多的环境
不同的磁盘调度算法(以及相应的 I/O 优化手段〉对 Kafka 这类依赖、磁盘运转的应用的影
响很大,建议根据不同的业务需求来测试并选择合适的磁盘调度算法。
从文件系统层面分析, Kafka 操作的都是普通文件,并没有依赖于特定的文件系统,但是
依然推荐使用 EXT4 XFS 尤其是对 XFS 而言,它通常有更好的性能 ,这种性能的提升 主要
影响的是 Kafka 写入性能

你可能感兴趣的:(工具,缓存)