6.4.3. Noop
Noop I/O 调度程序采用先入先出(FIFO)调度算法。合并原始块层中的请求,但只是一个最后命中缓存(last-hit cache)。如果系统与 CPU 捆绑,且使用高速存储,这就是可以使用的最佳 I/O 调度程序。
以下是块层中可以使用的可调参数。
/sys/block/sdX/queue 可调参数
- add_random
- 在某些情况下,熵池中用于
/dev/random
的 I/O 事件成本是可以测量的。在某些情况下要求将其设定为 0。 max_sectors_kb
- 默认将发送到磁盘的最大请求设定为
512
KB。这个可调参数可用来增大或者减小该值。最小值为逻辑块大小;最大值由max_hw_sectors_kb
设定。有些 SSD 会在 I/O 大小超过内部删除块大小时性能下降。在此类情况下建议将max_hw_sectors_kb
降低到删除块大小。您可以使用类似 iozone 或者 aio-stress 的 I/O 生成程序对此进行测试,记录大小可从512
字节到1
MB 不等。 nomerges
- 这个可调参数主要用于故障排除。大多数负载都可从请求合并中获益(即使类似 SSD 的告诉存储也是如此)。但在有些情况下要求禁用合并,比如当您要查看存储后端可处理多少 IOPS 而无需禁用预读或者执行随机 I/O 时。
nr_requests
- 每个请求队列都有可为每个读和写 I/O 分配的请求描述符总数限制。这个数的默认值为
128
,即在将某个进程转入睡眠模式时可将 128 个读和 128 个写放入队列。转入睡眠模式的进程是下一个要分配请求的进程,不一定是已分配所有可用请求的进程。如果您一个对延迟敏感的程序,则应考虑在您的请求队列中降低nr_requests
值,并将存储中的命令队列深度降低到较低的数值(甚至可以降低为1
),这样写回 I/O 就无法分配所有可用请求描述符,并使用写入 I/O 设备队列填满该设备。分配nr_requests
后,所有其他尝试执行 I/O 的进程都会转入睡眠模式等待请求可用。这样更为公平,因为这样会以轮循模式分配请求(而不是让一个进程很快消耗完所有资源)。注:只有在使用最后期限或者 noop 调度程序时才会有此问题,因为默认 CFQ 配置可防止出现此类情况。 optimal_io_size
- 在有些情况下,底层存储会报告最佳 I/O 大小。这在硬件和软件 RAID 中很常见,其中最佳 I/O 大小是条大小。如果报告该值,则程序应该发出以及最佳 I/O 大小相当会长成倍数的大小的 I/O。
read_ahead_kb
- 操作系统可探测到程序何时从文件或者磁盘中连续读取数据。在这种情况下,它可执行智能预读算法,因此用户可能会要求从磁盘中读取更多数据。因此当用户下一步尝试读取数据块时,它已经在操作系统的页缓存中了。可能的缺点是操作系统可能从磁盘中读取过多数据,这样就会占用页缓存直到高内存压力将其清除。如果有多个进程执行错误预读就会增加这种情况下的内存压力。对于设备映射器设备,一般应该增大
read_ahead_kb
值,比如8192
。理由是设备映射器设备通常有多个基础设备组成。将其设定为默认的值(128
KB)然后乘以要映射的设备数是个好的调整起点。 rotational
- 传统硬盘一般都采用轮换模式(比如转盘)。但 SSD 不是。大多数 SSD 会以适当的方式进行宣传。但如果您遇到设备没有说明有此功能,则可能需要手动将轮换模式设定为
0
;禁用轮换模式后,I/O 提升程序就不使用要减少查询的逻辑,因为在非轮换介质中会有少量查询操作罚分。 rq_affinity
- 可在与发出 I/O 不同的 CPU 中处理 I/O。将
rq_affinity
设定为1
可让内核向发出 I/O 的 CPU 传递完成信息。这样可以改进 CPU 数据缓存效果。