ZFS I/O (ZIO) 调度器

ZFS 向叶子 vdev(通常是设备)发出 I/O 操作以满足并完成 I/O 请求。ZIO 调度器决定这些操作的发出时间和顺序。操作被分为五个 I/O 类别,按以下优先级排序:

每个队列定义了向设备发出的并发操作的最小和最大数量。此外,设备还有一个总的最大值,即 zfs_vdev_max_active。请注意,每个队列的最小值之和不能超过总的最大值。如果每个队列的最大值之和超过总的最大值,则活动的 I/O 数量可能达到 zfs_vdev_max_active,在这种情况下,无论是否满足所有队列的最小值,都不会再发出更多的 I/O。

对于许多物理设备,吞吐量随着并发操作数量的增加而增加,但延迟通常会受到影响。此外,物理设备通常有一个限制,超过该限制后,更多的并发操作对吞吐量没有影响,甚至可能导致磁盘性能下降。

ZIO 调度器通过首先查找未满足最小值的 I/O 类别来选择下一个要发出的操作。一旦所有类别都满足且未达到总的最大值,调度器会查找未满足最大值的类别。按照上述顺序遍历 I/O 类别。如果已达到总的最大并发操作数量,或者没有为未达到最大值的 I/O 类别排队的操作,则不会发出更多的操作。每次 I/O 排队或操作完成时,I/O 调度器都会查找新的操作来发出。

一般来说,较小的 max_active 值会导致同步操作的延迟较低。较大的 max_active 值可能会提高整体吞吐量,具体取决于底层存储和 I/O 混合情况。

队列的 max_active 值的比率决定了读取、写入和扫描之间的性能平衡。例如,当存在争用时,增加 zfs_vdev_scrub_max_active 会使 scrub 或 resilver 更快完成,但读取和写入的延迟会更高,吞吐量会降低。

所有 I/O 类别都有一个固定的最大未完成操作数量,除了异步写入类别。异步写入表示在事务组(txg)同步阶段提交到稳定存储的数据。事务组定期进入同步状态,因此排队的异步写入数量会迅速增加,然后减少到零。zfs_txg_timeout 可调参数(默认=5 秒)设置了 txg 同步的目标间隔。因此,每 5 秒一次的异步写入突发是 ZFS 的正常 I/O 模式。

ZIO 调度器不是尽可能快地处理 I/O,而是根据池中脏数据的数量来调整异步写入 I/O 的最大活动数量。由于吞吐量和延迟通常随着向物理设备发出的并发操作数量的增加而增加,减少并发操作的突发性也稳定了其他队列操作的响应时间。这对于同步读取和写入队列尤为重要,因为 txg 同步的周期性异步写入突发可能导致设备级争用。简而言之,ZIO 调度器在池中有更多脏数据时,会从异步写入队列中发出更多的并发操作。