我正在尝试配置 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
最佳答案
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 的驱动器默认添加一个。
–
|
–
–
fio
当您这样做的时候,您能否用不同的方式重新运行bs
,比如说,64k
这次?–
–
–
|