我正在尝试配置 MD RAID1(使用 mdadm),--write-mostly以便网络(EBS)卷和本地驱动器互为镜像(想法是本地驱动器对我的实例来说是短暂的,但具有更好的性能)。

为了验证这个想法,我使用以下两个脚本对我的驱动器进行了基准性能评估。

fio -name=RandWrite -group_reporting -allow_file_create=0 \
  -direct=1 -iodepth=128 -rw=randwrite -ioengine=io_uring -bs=32k \
  -time_based=1 -ramp_time=10 -runtime 10 -numjobs=8 \
  -randrepeat=0 -norandommap=1 -filename=$BENCHMARK_TARGET

# Read performance
fio -name=RandRead -group_reporting -allow_file_create=0 \
  -direct=1 -iodepth=128 -rw=randread -ioengine=io_uring -bs=32k \
  -time_based=1 -ramp_time=10 -runtime 10 -numjobs=8 \
  -randrepeat=0 -norandommap=1 -filename=$BENCHMARK_TARGET

结果:

  • 网络驱动器:写入速度为 117 MiB/s,读取速度为 117 MiB/s
  • 本地驱动器:写入速度为 862 MiB/s,读取速度为 665 MiB/s

当我引入 mdadm 时,问题就出现了。即使使用简单的无镜像“RAID1”,使用网络驱动器时写入性能也会严重下降。

mdadm --build /dev/md0 --verbose --level=1 --force --raid-devices=1 "$TARGET"
# mdadm --detail /dev/md0
/dev/md0:
           Version :
     Creation Time : Mon Sep 30 14:22:41 2024
        Raid Level : raid1
        Array Size : 10485760 (10.00 GiB 10.74 GB)
     Used Dev Size : 10485760 (10.00 GiB 10.74 GB)
      Raid Devices : 1
     Total Devices : 1

             State : clean
    Active Devices : 1
   Working Devices : 1
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : resync

    Number   Major   Minor   RaidDevice State
       0       8       16        0      active sync   /dev/sdb
  • 由网络驱动器支持的 0 镜像 RAID1 阵列:写入速度为 69.9 MiB/s,读取速度为 118 MiB/s
  • 由本地驱动器支持的 0 镜像 RAID1 阵列:写入速度为 868 MiB/s,读取速度为 665 MiB/s

我们在这里可以看到,本地驱动器(MD-raid 与原始访问)的写入性能没有太大变化,但通过 MD-raid 使用网络驱动器时,写入性能会严重受损。为什么会发生这种情况?

5

  • 您是否尝试过在两种情况下重复测量?这些测量受计算机状态的影响,而计算机通常无法得到很好的控制,并且相同设置的不同测量可能会产生不同的数字。例如,进行 5 次测量并计算平均值和标准偏差。


    – 


  • 我已经运行了几十次这个实验,并在此过程中多次从头开始重新创建服务器/卷。所以这不是一个一次性的问题,我可以可靠地重现它。我相信在运行矩阵式基准测试后,我最终找到了原因。我还没有尝试过 ZFS、Btrfs 或 Bcachefs。这些可能有用,但我想要 RAID1 设置的简单性(其中驱动器可以单独用作普通驱动器,而无需任何特殊配置)。


    – 

  • fio当您这样做的时候,您能否用不同的方式重新运行bs,比如说,64k这次?


    – 

  • 原始驱动器的吞吐量增加到 32k 然后趋于平稳,而 IOPS 则下降(显然)。


    – 

  • Bcache 基本上是为从快速缓存到慢速存储的确切用例而设计的,您应该尝试一下 bcache 🙂


    – 


最佳答案
3

在不知道 mdadm 确切实现的情况下,我只能对此写下我的有根据的猜测。

我认为在 RAID 1 设置中,RAID 子系统会等待两个驱动器确认写入操作,然后再处理下一个文件事件。然后驱动器之间的性能不匹配可能会带来额外的延迟,这会导致 69.9 MiB/s 与 117 MiB/s 的写入速度。

我认为使用访问速度差异很大的设备创建 RAID 阵列是不可行的。RAID 不是为这种用例设计的。

您可能需要查看集群文件系统(例如 GFS2 或 OCFS2),它们可能更适合您的用例。

4

  • 我也是这么想的;延迟可能存在数量级的差异,这会导致大量的阻塞。


    – 

  • 2
    我试图说清楚,但还是要重复一遍:这些数字来自未镜像的“假”RAID1。从“mdadm –detail”的输出中可以看出,当我运行这些测试时,只有 1 个驱动器在运行。


    – 

  • MD 设备中没有两个驱动器,因此系统始终只等待一个驱动器。


    – 

  • RAID wasn't designed for this use case.– 但 Bcache为这种用例设计的。建议 OP 查看 Bcache


    – 


据我所知,这是由于 MD 内核模块的 IOPS 过载导致的故障模式。

当我修改脚本以使用 iodepth=64 numjobs=1 时,我看到原始驱动器上的性能没有损失,并且我的 RAID1 写入性能影响消失了。

以下是最终的脚本:

fio -name=RandWrite -group_reporting -allow_file_create=0 \
    -iodepth=$IODEPTH -numjobs=$NUMJOBS \
    -direct=1 -rw=randwrite -ioengine=io_uring -bs=16k \
    -time_based=1 -ramp_time=10 -runtime 10 \
    -randrepeat=0 -norandommap=1 -filename=$DEVICE
fio -name=RandRead -group_reporting -allow_file_create=0 \
    -iodepth=$IODEPTH -numjobs=$NUMJOBS \
    -direct=1 -rw=randread -ioengine=io_uring -bs=16k \
    -time_based=1 -ramp_time=10 -runtime 10 -randrepeat=0 \
    -norandommap=1 -filename=$DEVICE

最终结果如下:

公制 io深度=128
作业数量=8
io深度=64
作业数=1
本地磁盘,写入 629 766
本地磁盘,读取 754 877
云盘,写入 117 117
云盘,阅读 118 117
RAID1,本地,写入 526 775
RAID1,本地,读取 751 853
RAID1、云、写入 59 117
RAID1、云、读取 115 117
RAID1,两者皆可写入 61 117
RAID1,两者,读取 755 879

我猜想过多的 IOPS 加上较慢的驱动器会导致队列长度过长,进而导致内核模块中出现某种锁争用。但我对细节了解不够,无法确定。我了解到的是,我需要一个更准确的基准来正确决定这种方法是否适合我的用例。

1

  • 请记得接受答案。


    – 

您可能受到 MD 写入位图的限制。您可以尝试禁用它(通过--bitmap=none创建期间或稍后使用--grow),但请务必了解,在没有位图的阵列上不正常关闭意味着重新启动后完全重新同步。

1

  • 猜得不错!不过我可以确认没有使用位图。位图将使用“位图”一致性策略,但您可以看到我拥有的是“重新同步”。文档说默认情况下,mdadm 只会为超过 100G 的驱动器默认添加一个。


    –