我正在尝试配置 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 使用网络驱动器时,写入性能会严重受损。为什么会发生这种情况?
在不知道 mdadm 确切实现的情况下,我只能对此写下我的有根据的猜测。
我认为在 RAID 1 设置中,RAID 子系统会等待两个驱动器确认写入操作,然后再处理下一个文件事件。然后驱动器之间的性能不匹配可能会带来额外的延迟,这会导致 69.9 MiB/s 与 117 MiB/s 的写入速度。
我认为使用访问速度差异很大的设备创建 RAID 阵列是不可行的。RAID 不是为这种用例设计的。
您可能需要查看集群文件系统(例如 GFS2 或 OCFS2),它们可能更适合您的用例。
据我所知,这是由于 MD 内核模块的 IOPS 过载导致的故障模式。
当我修改脚本以使用 iodepth=64 numjobs=1 时,我看到原始驱动器上的性能没有损失,并且我的 RAID1 写入性能影响消失了。
以下是最终的脚本:
最终结果如下:
作业数量=8
作业数=1
我猜想过多的 IOPS 加上较慢的驱动器会导致队列长度过长,进而导致内核模块中出现某种锁争用。但我对细节了解不够,无法确定。我了解到的是,我需要一个更准确的基准来正确决定这种方法是否适合我的用例。
您可能受到 MD 写入位图的限制。您可以尝试禁用它(通过
--bitmap=none
创建期间或稍后使用--grow
),但请务必了解,在没有位图的阵列上不正常关闭意味着重新启动后完全重新同步。