在 Linux 上使用软件 RAID 和 LVM 时,哪些 IO 调度程序和预读设置受到尊重?

and*_*311 29 linux raid lvm

在多层(物理驱动器 -> md -> dm -> lvm)的情况下,调度程序、预读设置和其他磁盘设置如何交互?

假设您有多个磁盘 (/dev/sda - /dev/sdd),它们都是使用 mdadm 创建的软件 RAID 设备 (/dev/md0) 的一部分。每个设备(包括物理磁盘和 /dev/md0)都有自己的 IO 调度程序设置(像这样更改)和预读(使用 blockdev 更改)。当你加入 dm(加密)和 LVM 之类的东西时,你会添加更多具有自己设置的层。

例如,如果物理设备有 128 个数据块的预读,而 RAID 有 64 个数据块的预读,当我从 /dev/md0 读取时,这是正确的吗?md 驱动程序是否尝试读取 64 个块,然后物理设备驱动程序将其转换为 128 个块的读取?或者 RAID 预读是否“直通”到底层设备,导致读取 64 个块?

同样的问题也适用于调度程序?我是否必须担心多层 IO 调度程序以及它们如何交互,或者 /dev/md0 是否有效地覆盖了底层调度程序?

在我试图回答这个问题时,我挖掘了一些关于调度程序和工具的有趣数据,这些数据可能有助于解决这个问题:

sta*_*ark 8

如果您从 md0 读取,则使用 md0 的预读。如果您从作为 md0 组件的 sda 读取,那么它将使用 sda 设置。设备映射器只是将一个 I/O 拆分成多个读取和写入来执行 RAID,但这一切都在预读发生的块缓存层之下。存储堆栈如下所示:

文件系统 - 使用 O_DIRECT 打开时绕过缓存

块缓存 - 预读、写缓存、调度程序

设备映射器 - dm、lvm、软件 RAID、快照等。

sd - 磁盘驱动程序

SCSI - 错误处理、设备路由

硬件驱动程序 - scsi 卡、FC 卡、以太网

请注意,当您执行

dd if=/dev/sda of=foo
Run Code Online (Sandbox Code Playgroud)

您正在将 sda 作为文件读取,因此您正在通过块缓存。要直接转到磁盘,请执行

dd if=/dev/sda of=foo iflag=direct
Run Code Online (Sandbox Code Playgroud)

至于 I/O 电梯调度程序,它们只存在于磁盘驱动程序 (sd) 上。/sys/block/md 或 /sys/block/dm 下没有队列目录。您只需进行一次磁盘升降机排序。

  • 我的系统上有一个 `/sys/block/md0/queue/scheduler`,但唯一的选择是 `none`。 (2认同)