ZFS 池慢速顺序读取

Rya*_*hin 10 linux raid performance zfs zpool

我有一个关于这个问题的相关问题,但它太复杂和太大了,所以我决定我应该把这个问题分成 NFS 和本地问题。我也试过在 zfs-discuss 邮件列表上询问这个问题,但没有取得多大成功。

在同一服务器上的 NFS/CIFS 目录之间复制缓慢

大纲:我的设置方式以及我的期望

  1. 我有一个带有 4 个磁盘的 ZFS 池。2TB RED 配置为 2 个条带化镜像 (RAID 10)。在 Linux 上,zfsonlinux。没有缓存或日志设备。
  2. 数据跨镜像平衡(对 ZFS 很重要)
  3. 每个磁盘可以以 147MB/秒的速度并行读取(原始 w/dd),总吞吐量为 588MB/秒。
  4. 根据类似 4TB RED 磁盘的基准测试,我预计每个磁盘的顺序数据写入速度约为 115MB/秒、读取速度为 138MB/秒和重写速度为 50MB/秒。我希望读取或写入速度不低于 100MB/秒,因为现在任何磁盘都可以做到这一点。
  5. 我以为在负载读取或写入顺序数据时,我会在所有 4 个磁盘上看到 100% 的 IO 利用率。并且磁盘将在 100% 的利用率下输出超过 100MB/秒。
  6. 我认为池可以在单个磁盘上为我提供大约 2 倍的写入、2 倍的重写和 4 倍的读取性能——我错了吗?
  7. 我认为同一池上的 ext4 zvol 与 ZFS 的速度大致相同

我实际得到的

我发现池的读取性能没有我预期的那么高

几天前的bonnie++基准测试池

版本 1.97 ------顺序输出------ --顺序输入- --随机-
并发 1 -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
机器尺寸 K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
伊戈尔 63G 99 99 232132 47 118787 27 336 97 257072 22 92.7 6

bonnie++在 zpool 中的单个 4TB RED 驱动器上

版本 1.97 ------顺序输出------ --顺序输入- --随机-
并发 1 -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
机器尺寸 K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
伊戈尔 63G 101 99 115288 30 49781 14 326 97 138250 13 111.6 8

据此,基于单个 4TB RED 驱动器的结果,读取和重写速度是合适的(它们是两倍)。然而,我期望的读取速度大约是 550MB/秒(4TB 驱动器速度的 4 倍),我至少希望大约 400MB/秒。相反,我看到大约 260MB/秒

bonnie++从刚才开始在游泳池上,同时收集以下信息。和以前不太一样,也没有什么改变。

版本 1.97 ------顺序输出------ --顺序输入- --随机-
并发 1 -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
机器尺寸 K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
伊戈尔 63G 103 99 207518 43 108810 24 342 98 302350 26 256.4 18

写入期间的zpool iostat。对我来说似乎没问题。

                                                 容量操作带宽
池分配空闲读写读写
----------------------------------------- ----- - ---- ----- ----- ----- -----
池 2 1.23T 2.39T 0 1.89K 1.60K 238M
  镜面 631G 1.20T 0 979 1.60K 120M
    ata-WDC_WD20EFRX-68AX9N0_WD-WMC300004469 - - 0 1007 1.60K 124M
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4MLK57MVX - - 0 975 0 120M
  镜子 631G 1.20T 0 953 0 117M
    ata-WDC_WD20EFRX-68AX9N0_WD-WCC1T0429536 - - 0 1.01K 0 128M
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4M0VYKFCE - - 0 953 0 117M

重写期间的zpool iostat。对我来说似乎没问题,我想

                                                 容量操作带宽
池分配空闲读写读写
----------------------------------------- ----- - ---- ----- ----- ----- -----
pool2 1.27T 2.35T 1015 923 125M 101M
  镜面 651G 1.18T 505 465 62.2M 51.8M
    ata-WDC_WD20EFRX-68AX9N0_WD-WMC300004469 - - 198 438 24.4M 51.7M
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4MLK57MVX - - 306 384 37.8M 45.1M
  镜面 651G 1.18T 510 457 63.2M 49.6M
    ata-WDC_WD20EFRX-68AX9N0_WD-WCC1T0429536 - - 304 371 37.8M 43.3M
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4M0VYKFCE - - 206 423 25.5M 49.6M

这是我想知道发生了什么的地方

读取期间的zpool iostat

                                                 容量操作带宽
池分配空闲读写读写
----------------------------------------- ----- - ---- ----- ----- ----- -----
pool2 1.27T 2.35T 2.68K 32 339M 141K
  镜面 651G 1.18T 1.34K 20 169M 90.0K
    ata-WDC_WD20EFRX-68AX9N0_WD-WMC300004469 - - 748 9 92.5M 96.8K
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4MLK57MVX - - 623 10 76.8M 96.8K
  镜面 651G 1.18T 1.34K 11 170M 50.8K
    ata-WDC_WD20EFRX-68AX9N0_WD-WCC1T0429536 - - 774 5 95.7M 56.0K
    ata-WDC_WD20EFRX-68EUZN0_WD-WCC4M0VYKFCE - - 599 6 74.0M 56.0K

iostat -x在同一读取操作期间。请注意 IO % 不是 100%。

设备:rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdb 0.60 0.00 661.30 6.00 83652.80 49.20 250.87 2.32 3.47 3.46 4.87 1.20 79.76
标准差 0.80 0.00 735.40 5.30 93273.20 49.20 251.98 2.60 3.51 3.51 4.15 1.20 89.04
标准偏差 0.50 0.00 656.70 3.80 83196.80 31.20 252.02 2.23 3.38 3.36 6.63 1.17 77.12
sda 0.70 0.00 738.30 3.30 93572.00 31.20 252.44 2.45 3.33 3.31 7.03 1.14 84.24

zpool 和测试数据集设置:

  • 时间关闭
  • 压缩已关闭
  • ashift 为 0(自动检测 - 我的理解是这没问题)
  • zdb 说磁盘都是 ashift=12
  • 模块 - 选项 zfs zvol_threads=32 zfs_arc_max=17179869184
  • 同步 = 标准

编辑 - 2015 年 10 月 30 日

我做了更多的测试

  • 数据集 bonnie++ w/recordsize=1M = 226MB 写入,392MB 读取要好得多
  • 数据集 dd w/record size=1M = 260MB 写入,392MB 读取要好得多
  • zvol w/ext4 dd bs=1M = 128MB 写入,107MB 读取为什么这么慢?
  • 数据集 2 并行处理 = 227MB 写入,396MB 读取
  • dd direct io 在数据集和 zvol 上没有区别

我对增加记录大小的性能感到满意。池中几乎每个文件都超过 1MB。所以我会就这样离开它。磁盘仍然没有达到 100% 的利用率,这让我想知道它是否还能更快。现在我想知道为什么 zvol 性能如此糟糕,因为这是我(轻度)使用的东西。

我很高兴提供评论/答案中要求的任何信息。在我的另一个问题中也发布了大量信息:在同一服务器上的 NFS/CIFS 目录之间缓慢复制

我完全意识到我可能只是不明白某些事情,这可能根本不是问题。提前致谢。

明确地说,问题是:为什么 ZFS 池没有我预期的那么快?也许还有什么不对的吗?

Rya*_*hin 11

我设法使速度非常接近我期望的数字。

我正在寻找400MB/sec并管理392MB/sec。所以我说问题解决了。后来添加了一个缓存设备,我管理了458MB /秒的读取(我相信是缓存的)。

1.这最初只是通过将 ZFS 数据集recordsize值增加到1M

zfs set recordsize=1M pool2/test
Run Code Online (Sandbox Code Playgroud)

我相信这种变化只会减少磁盘活动,从而提高大型同步读取和写入的效率。正是我所要求的。

更改后的结果

  • bonnie++ = 226MB 写入,392MB 读取
  • dd = 260MB 写入,392MB 读取
  • 2 个并行进程 = 227MB 写入,396MB 读取

2.当我添加缓存设备(120GB SSD)时,我的管理更好。写的有点慢,我不知道为什么。

Version  1.97       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
igor            63G           208325  48 129343  28           458513  35 326.8  16
Run Code Online (Sandbox Code Playgroud)

缓存设备的技巧是l2arc_noprefetch=0/etc/modprobe.d/zfs.conf 中设置。它允许 ZFS 缓存流/顺序数据。仅当您的缓存设备比您的阵列(例如我的)快时才执行此操作。

在从我的数据集上的记录大小更改中受益后,我认为这可能是一种类似的方法来处理糟糕的 zvol 性能。

我遇到严重的人提到他们使用 a 获得了良好的性能volblocksize=64k,所以我尝试了它。没运气。

zfs create -b 64k -V 120G pool/volume
Run Code Online (Sandbox Code Playgroud)

但是后来我读到 ext4(我正在测试的文件系统)支持像stridestripe-width这样的RAID 选项,我以前从未使用过。所以我使用这个网站来计算所需的设置:https : //busybox.net/~aldot/mkfs_stride.html 并再次格式化 zvol。

mkfs.ext3 -b 4096 -E stride=16,stripe-width=32 /dev/zvol/pool/volume
Run Code Online (Sandbox Code Playgroud)

我跑bonnie++做一个简单的基准测试,结果非常好。不幸的是,我没有结果,但据我回忆,它们的写入速度至少快了 5-6 倍。如果我再次进行基准测试,我会再次更新此答案。