在多层(物理驱动器 -> 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 是否有效地覆盖了底层调度程序?
在尝试回答这个问题的过程中,我挖掘了一些有关调度程序和工具的有趣数据,这些数据可能有助于弄清楚这一点:
答案1
如果您从 md0 读取,则使用 md0 的预读。如果您从 sda(md0 的组件)读取,则它将使用 sda 设置。设备映射器只是将 I/O 拆分为多个读取和写入以执行 RAID,但这一切都在预读发生的块缓存层之下。存储堆栈如下所示:
文件系统-使用 O_DIRECT 打开时绕过缓存
块缓存 - 预读、写缓存、调度程序
设备映射器——dm、lvm、软件 RAID、快照等。
sd——磁盘驱动程序
SCSI——错误处理、设备路由
硬件驱动程序 - scsi 卡、FC 卡、以太网
请注意,当你这样做
dd if=/dev/sda of=foo
您正在将 sda 读取为文件,因此您正在浏览块缓存。要直接转到磁盘,请执行以下操作
dd if=/dev/sda of=foo iflag=direct
至于 I/O 电梯调度程序,它们仅存在于磁盘驱动器 (sd) 上。/sys/block/md 或 /sys/block/dm 下没有队列目录。您只需进行一次磁盘电梯排序。