为什么 mdadm 在同步挂载时写入速度慢得无法使用?

为什么 mdadm 在同步挂载时写入速度慢得无法使用?

我有一个 6 磁盘 raid6 mdadm 阵列,我想对写入进行基准测试:

root@ubuntu:~# cat /proc/mdstat 
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid6 sda[0] sdf[5] sde[4] sdd[3] sdc[2] sdb[1]
      1953545984 blocks level 6, 64k chunk, algorithm 2 [6/6] [UUUUUU]

由于缓存的原因,基准测试可能不准确 - 例如,请注意此处的写入速度高于应有的速度:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.276026 s, 380 MB/s

现在我们可以很轻松地禁用每个磁盘缓存:

root@ubuntu:~# hdparm -W0 /dev/sd*

/dev/sda:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdb:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdc:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdd:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sde:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdf:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

但Linux缓存仍然存在:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00566339 s, 1.9 GB/s

要禁用 Linux 缓存,我们可以同步挂载文件系统:

mount -o remount,sync /mnt/raid6

但在此之后写成了方式比应有的速度慢:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 23.3311 s, 449 kB/s

好像 mdadm 需要异步挂载才能运行。这是怎么回事?

答案1

提问者引述:

但Linux缓存仍然存在:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00566339 s, 1.9 GB/s

要禁用 Linux 缓存,我们可以同步挂载文件系统:

mount -o remount,sync /mnt/raid6

这不太对……同步并不是像基准测试中那样简单地禁用缓存。它使每次写入都产生“同步”命令,这意味着将缓存全部刷新到磁盘。

这里有一个服务器,为了更好地解释:

$ dd if=/dev/zero of=testfile bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.183744 s, 2.9 GB/s

$ dd if=/dev/zero of=testfile bs=1M count=500 conv=fdatasync
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 5.22062 s, 100 MB/s

conv=f​​datasync 只是表示写入后刷新,并告诉您包括刷新在内的时间。或者,您可以执行以下操作:

$ time ( dd if=/dev/zero of=testfile bs=1M count=500 ; sync )
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.202687 s, 2.6 GB/s

real    0m2.950s
user    0m0.007s
sys     0m0.339s

然后根据 2.95 秒的实时时间(而不是上面的 0.2 秒)计算 MB/s。但这样比较丑陋,工作量也更大,因为 dd 打印的统计数据不包括同步。

如果您使用“同步”,您将刷新每个写入...可能这意味着每个块,这将运行非常慢。 “同步”应该只在非常严格的系统上使用,例如数据库,其中由于磁盘故障而导致单个事务的丢失是不可接受的(例如,如果我将十亿美元从我的银行账户转移到你的银行账户,并且系统崩溃,突然你有了钱,但我也有)。

这是我很久以前读过的另一种带有附加选项的解释。 http://romanrm.ru/en/dd-benchmark

还有一点需要注意:在我看来,您以这种方式进行的基准测试完全有效,尽管在许多其他人看来并不有效。但这不是实际测试。这是一个单线程顺序写入。如果您的实际用例是这样的,例如通过网络发送一些大文件,那么它可能是一个很好的基准。如果您的用例不同,例如 500 人同时上传小文件的 ftp 服务器,那么它就不是很好。

此外,为了获得最佳效果,您应使用 RAM 上随机生成的文件。它应该是随机数据,因为有些文件系统在输入零时会变得非常聪明。例如,在 Linux 上使用挂载在 /dev/ 上的 RAM 文件系统 tmpfs。它应该是 RAM fs,而不是直接使用 /dev/urandom,因为 /dev/random 真的很慢,而 /dev/urandom 更快(例如 75MB/s),但仍然比 hdd 慢。

dd if=/dev/urandom of=/dev/shm/randfile bs=1M count=500
dd if=/dev/shm/randfile bs=1M count=500 conv=fdatasync

答案2

由于同步写入强制奇偶校验计算对磁盘造成影响,因此性能急剧下降。

一般来说,计算和写入奇偶校验是一个相对较慢的过程,尤其是使用 RAID 6 时——在您的例子中,md 不仅必须将数据分割成四个块,然后还要为每个条带计算两个奇偶校验块。为了提高性能,RAID 实现(包括 md)将在内存中缓存最近使用的条带,以便将要写入的数据与现有数据进行比较,并在写入时快速重新计算奇偶校验。如果将新数据写入缓存的条带,它可以比较、分割和重新计算奇偶校验,而无需接触磁盘,然后稍后刷新它。您创建了一种 md 总是错过缓存的情况,在这种情况下,它必须从磁盘读取条带,比较数据,分割新数据,重新计算奇偶校验,然后将新条带直接刷新到磁盘。缓存命中时需要从磁盘零次读取和写入,现在需要六次读取和六次写入每写一条条纹。

诚然,您观察到的性能差异是巨大的(1.9GB/s 对 449KB/s),但我认为这都是由于 md 为维护数据完整性所做的工作量造成的。

这种性能下降可能会因磁盘的排列方式而加剧……如果将它们全部放在一个控制器上,那么过多的读写操作将导致性能陷入停滞。

答案3

您能告诉我们您的 6 个磁盘是如何组成的吗?在我看来,它们好像是 SAN/DAS 的任何目标的一部分 - 可能由相同的物理磁盘组成(因此,如果所有 6 个磁盘都位于同一个磁盘上,与单个磁盘相比,这将使性能降低 6 个)。

请查看此 anwerleaks.com 链接。

那么您是如何设置位图的?

相关内容