在Linux上使用软件RAID和LVM时,哪个IO调度程序和预读设置得到遵守?

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

假设你有几个磁盘(/ dev / sda – / dev / sdd)是由mdadm创build的软件RAID设备(/ dev / md0)的所有部分。 每个设备(包括物理磁盘和/ dev / md0)都有自己的IO调度器设置( 如此更改 )和readahead( 使用blockdev更改 )。 当你扔dm(crypto)和LVM之类的东西时,你可以添加更多的图层和自己的设置。

例如,如果物理设备的读取超过了128个块,并且RAID有64个块的先行读取,当我从/ dev / md0读取数据时,这是可以使用的吗? 是否md驱动程序尝试64块读取,物理设备驱动程序然后转换为128块的读取? 或者,RAID是否提前“传递”到底层设备,导致64块读取?

调度人员也有同样的问题吗? 我是否必须担心IO调度程序的多个层次以及它们如何交互,或者/ dev / md0是否有效地覆盖了基础调度程序?

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

  • 来自Google的Linux磁盘调度器基准testing
  • blktrace – 在块设备上生成I / Ostream量的跟踪
  • 相关的Linux内核邮件列表线程

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

文件系统 – 用O_DIRECT打开时绕过caching

块caching – 预读,写caching,调度程序

device-mapper -dm,lvm,软件RAID,快照等

sd – 磁盘驱动程序

SCSI – error handling,设备路由

硬件驱动程序 – scsi卡,FC卡,以太网

请注意,当你这样做

dd if=/dev/sda of=foo 

你正在读sda作为一个文件,所以你正在通过块caching。 要直接进入磁盘,请执行

 dd if=/dev/sda of=foo iflag=direct 

至于I / O电梯调度程序,这些调度程序只存在于磁盘驱动程序(sd)中。 / sys / block / md或/ sys / block / dm下没有队列目录。 你只能通过磁盘电梯一次。