我有一个关于这个问题的相关问题,但是它太复杂而且太大了,所以我决定我应该把这个问题分成 NFS 和本地问题。我也尝试在 zfs-discuss 邮件列表上询问这个问题,但没有取得多大成功。
大纲:我是如何设置的以及我的期望
- 我有一个带有 4 个磁盘的 ZFS 池。2TB RED 配置为 2 个条带化镜像 (RAID 10)。在 Linux 上,zfsonlinux。没有缓存或日志设备。
- 跨镜像平衡数据(对 ZFS 很重要)
- 每个磁盘可以以 147MB/秒的速度并行读取(原始 w/dd),总吞吐量为 588MB/秒。
- 根据类似 4TB RED 磁盘的基准,我预计每个磁盘的顺序数据写入速度约为 115MB/秒,读取速度为 138MB/秒,重写速度为 50MB/秒。我预计读取或写入速度不会低于 100MB/秒,因为现在任何磁盘都可以做到这一点。
- 我想当负载读取或写入顺序数据时,我会看到所有 4 个磁盘上 100% 的 IO 利用率。并且磁盘将在 100% 的利用率下输出超过 100MB/秒。
- 我认为该池将在单个磁盘上为我提供大约 2 倍的写入、2 倍的重写和 4 倍的读取性能——我错了吗?
- 新我认为同一池上的 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在写入期间。对我来说似乎还可以。
容量操作带宽 pool alloc free 读写 读写 -------------------------------------------- ----- - ---- ----- ----- ----- ----- 池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 。对我来说似乎没问题,我想。
容量操作带宽 pool alloc free 读写 读写 -------------------------------------------- ----- - ---- ----- ----- ----- ----- 池2 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
容量操作带宽 pool alloc free 读写 读写 -------------------------------------------- ----- - ---- ----- ----- ----- ----- 池2 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 sdd 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 和测试数据集设置:
- atime 已关闭
- 压缩已关闭
- 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 性能如此糟糕,因为这是我(轻轻地)使用的东西。
我很高兴提供评论/答案中要求的任何信息。在我的另一个问题中还发布了大量信息:Slow copy between NFS/CIFS directory on the same server
我完全意识到我可能只是不明白某些事情,这可能根本不是问题。提前致谢。
为了清楚起见,问题是:为什么 ZFS 池没有我预期的那么快?也许还有什么问题吗?
我设法使速度非常接近我的预期。
我正在寻找400MB/sec并管理392MB/sec。所以我说问题解决了。后来添加了一个缓存设备,我管理了 458MB /秒的读取(我相信缓存)。
1.这最初是通过将 ZFS 数据集
recordsize
值增加到1M
我相信这种变化只会导致更少的磁盘活动,从而更有效地进行大型同步读取和写入。正是我所要求的。
更改后的结果
2.添加缓存设备(120GB SSD)后,我的管理更加出色。写的有点慢,不知道为什么。
缓存设备的技巧是
l2arc_noprefetch=0
在/etc/modprobe.d/zfs.conf 中设置。它允许 ZFS 缓存流/顺序数据。只有当你的缓存设备比你的阵列快时才这样做,比如我的。从我的数据集上的记录大小更改中受益后,我认为这可能是处理较差 zvol 性能的类似方法。
我遇到过严格的人提到他们使用 a 获得了良好的性能
volblocksize=64k
,所以我尝试了一下。没运气。但后来我读到 ext4(我正在测试的文件系统)支持 RAID 的选项,比如
stride
andstripe-width
,这是我以前从未使用过的。所以我使用这个站点来计算所需的设置:https : //busybox.net/~aldot/mkfs_stride.html 并再次格式化 zvol。我跑去
bonnie++
做了一个简单的基准测试,结果非常好。不幸的是,我没有结果,但我记得它们的写入速度至少快了 5-6 倍。如果我再次进行基准测试,我将再次更新此答案。您的结果是完全合理的,而您的期望却并非如此:您夸大了 RAID1(以及,通过扩展,RAID10)提供的读取性能改进。关键是 2 路镜像最多可提供2 倍的单个磁盘的读取速度/IOP,但实际性能可能在 1 倍至 2 倍之间。
让我们用一个例子来澄清一下。想象一下,有一个具有 2 路镜像的系统,每个磁盘的速度为 100 MB/s(顺序)和 200 IOPS。队列深度为 1(最多单个未完成的请求)时,该阵列对单个磁盘没有优势:RAID1 将 IO 请求拆分到两个磁盘的队列上,但它不会将单个请求拆分到两个磁盘(至少,我看到的任何实现都以这种方式表现)。另一方面,如果您的 IO 队列更大(例如:您有 4/8 个未完成的请求),总磁盘吞吐量将显着高于单个磁盘。
可以对 RAID0 进行类似的操作,但在这种情况下,决定平均改进的因素不仅是队列大小,还有IO 请求大小:如果您的平均 IO 大小低于块大小,那么它不会被条带化在两个(或更多)磁盘上,但它将由一个磁盘提供服务。增加 Bonnie++ 记录大小的结果显示了这种确切的行为:条带化极大地受益于更大的 IO 大小。
现在应该清楚的是,在 RAID10 阵列中组合两个 RAID 级别不会导致线性性能扩展,但会为它设置一个上限。我很确定,如果您运行多个 dd/bonnie++ 实例(或用于
fio
直接操作 IO 队列),您将获得更符合您最初期望的结果,这仅仅是因为您将以更完整的方式对 IO 数组征税(多个未完成的顺序/随机 IO 请求),而不是单独加载单个顺序 IO 请求。zfs 写入速度不是很快但也不错。zfs 读取速度极慢,自行查看:1) #Preparation: cd /mytestpool/mytestzfs;for f in urf{0..9};do dd if=/dev/urandom of=$f bs=1M count =102400;完成;#获取包含大量子目录和文件(约 50GB)的目录路径并检查大小,例如:du -sh /mytestpool/mytestzfs/appsdir 2) reboot 3) time cat /mytestpool/mytestzfs/urf0 >/dev/null; date;for f in /mytestpool/mytestzfs/urf{1..9};do cat $f >/dev/null & wait;done;date ; time tar cf - /mytestpool/mytestzfs/appsdir|cat - >/dev/null 4) #查看 iostat、iotop 或 zpool iostat:你看到了很多!5) 读取完成后,用计算器除以 singlefilesize/sec,除以 9x singlefilessize/sec 并除以 directorysize/sec。那'