一个相当基本的系统,在 7.2k rpm sas 磁盘上运行镜像+条带,没有特别加载。没有重复数据删除,所有数据集都压缩。Scrub 已经以死蜗牛的速度运行了 15 天。是否需要进行一些优化,或者可能是由于某些硬件故障?
- 带有 MD1200 外壳的 Dell R510。
- 2个Xeon E5620
- 48GB
- NexentaStor 3.1.3,社区版
一些信息:
scan: scrub in progress since Mon Apr 1 19:00:05 2013
171G scanned out of 747G at 141K/s, 1187h40m to go
0 repaired, 22.84% done
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
c7t5000C500414FB2CFd0 ONLINE 0 0 0
c7t5000C500414FCA57d0 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
c7t5000C500415C3B1Bd0 ONLINE 0 0 0
c7t5000C500415C5E4Fd0 ONLINE 0 0 0
mirror-2 ONLINE 0 0 0
c7t5000C500415DC797d0 ONLINE 0 0 0
c7t5000C500415DC933d0 ONLINE 0 0 0
logs
c7t5000A7203006D81Ed0 ONLINE 0 0 0
cache
c7t5000A72030068545d0 ONLINE 0 0 0
# iostat -en
---- errors ---
s/w h/w trn tot device
0 8887 0 8887 c2t0d0
0 0 0 0 c0t395301D6B0C8069Ad0
0 0 0 0 c7t5000C500415DC933d0
0 0 0 0 c7t5000A72030068545d0
0 0 0 0 c7t5000C500415DC797d0
0 0 0 0 c7t5000C500414FCA57d0
0 0 0 0 c7t5000C500415C3B1Bd0
0 0 0 0 c7t5000C500415C5E4Fd0
0 0 0 0 c7t5000C500414FB2CFd0
0 0 0 0 c7t5000A7203006D81Ed0
每次运行这个程序时,spa_last_io 都会改变
# echo "::walk spa | ::print spa_t spa_name spa_last_io spa_scrub_inflight" | mdb -k
spa_name = [ "syspool" ]
spa_last_io = 0x25661402
spa_scrub_inflight = 0
spa_name = [ "tank" ]
spa_last_io = 0x25661f84
spa_scrub_inflight = 0x21
每 5 秒,写入速度约为 20-25 MB/s。在这些写入之间,基本上没有读取或写入。
capacity operations bandwidth latency
pool alloc free read write read write read write
------------------------- ----- ----- ----- ----- ----- ----- ----- -----
syspool 427G 501G 0 0 0 0 0.00 0.00
c0t395301D6B0C8069Ad0s0 427G 501G 0 0 0 0 0.00 0.00
------------------------- ----- ----- ----- ----- ----- ----- ----- -----
tank 903G 1.84T 810 5.21K 1.50M 20.8M 9.42 4.71
mirror 301G 627G 22 1.00K 53.0K 3.96M 8.96 3.93
c7t5000C500414FB2CFd0 - - 20 244 50.1K 3.97M 6.70 1.14
c7t5000C500414FCA57d0 - - 19 242 48.2K 3.97M 7.60 1.12
mirror 301G 627G 25 1016 46.8K 4.10M 16.11 5.28
c7t5000C500415C3B1Bd0 - - 21 257 41.6K 4.11M 4.63 1.24
c7t5000C500415C5E4Fd0 - - 21 255 43.0K 4.11M 16.54 1.15
mirror 301G 627G 62 754 119K 3.03M 19.72 3.78
c7t5000C500415DC797d0 - - 57 219 114K 3.03M 9.99 1.15
c7t5000C500415DC933d0 - - 56 220 119K 3.03M 13.20 1.22
c7t5000A7203006D81Ed0 260K 46.5G 0 0 0 0 0.00 0.00
cache - - - - - -
c7t5000A72030068545d0 93.1G 8M 0 0 0 0 0.00 0.00
------------------------- ----- ----- ----- ----- ----- ----- ----- -----
iostats 是否告诉我我等待磁盘的时间比实际的要长?特别是 %b 列
# iostat -xe
device r/s w/s kr/s kw/s wait actv svc_t %w %b s/w h/w trn tot
sd3 5.1 43.9 20.6 643.8 0.0 0.1 2.9 0 5 0 0 0 0
sd4 9.4 1.8 141.1 169.6 0.0 0.0 0.5 0 0 0 0 0 0
sd5 3.1 43.8 15.8 643.8 0.0 0.1 1.4 0 3 0 0 0 0
sd6 5.2 38.1 14.3 494.4 0.0 0.1 3.0 0 7 0 0 0 0
sd7 4.2 40.2 11.1 623.2 0.0 0.1 2.7 0 7 0 0 0 0
sd8 3.6 44.3 9.7 623.2 0.0 0.1 1.5 0 4 0 0 0 0
sd9 2.9 37.4 7.0 494.4 0.0 0.1 1.3 0 2 0 0 0 0
sd10 0.7 0.4 3.4 0.0 0.0 0.0 0.0 0 0 0 0 0 0
延迟是不是有点高?
# zpool iostat 10 10
capacity operations bandwidth latency
pool alloc free read write read write read write
tank 909G 1.83T 86 2.82K 208K 12.7M 22.68 13.63
---------- ----- ----- ----- ----- ----- ----- ----- -----
tank 909G 1.83T 29 857 42.4K 3.50M 17.86 4.47
---------- ----- ----- ----- ----- ----- ----- ----- -----
tank 909G 1.83T 30 947 46.1K 3.54M 15.55 5.67
进行了一些调整,但没有什么区别。zfs_top_maxinflight 设置为 127,zfs_scrub_delay 设置为 0,zfs_scan_idle 设置为 0。
# echo zfs_top_maxinflight | mdb -k
zfs_top_maxinflight:
zfs_top_maxinflight: 127
# echo zfs_scrub_delay/D |mdb -k
zfs_scrub_delay:
zfs_scrub_delay:0
# echo zfs_scan_idle/D |mdb -k
zfs_scan_idle:
zfs_scan_idle: 0
scan: scrub in progress since Wed Apr 17 20:47:23 2013
1.85G scanned out of 918G at 1.14M/s, 229h36m to go
0 repaired, 0.20% done
在进行 mdb 调整之前,请注意相当高的 b% 列
$ iostat -nx -M 5
r/s w/s Mr/s Mw/s wait actv wsvc_t asvc_t %w %b device
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t0d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c0t395301D6B0C8069Ad0
35.2 44.2 0.3 0.7 0.0 0.4 0.0 5.3 0 32 c7t5000C500415DC933d0
19.8 3.2 0.2 0.0 0.0 0.0 0.0 0.1 0 0 c7t5000A72030068545d0
31.2 46.2 0.2 0.7 0.0 0.3 0.0 4.4 0 27 c7t5000C500415DC797d0
30.6 46.8 0.2 0.8 0.0 0.4 0.0 4.6 0 28 c7t5000C500414FCA57d0
37.6 53.0 0.3 0.8 0.0 0.4 0.0 4.7 0 33 c7t5000C500415C3B1Bd0
37.6 53.6 0.3 0.8 0.0 0.5 0.0 5.6 0 39 c7t5000C500415C5E4Fd0
33.2 46.8 0.3 0.8 0.0 0.5 0.0 6.1 0 33 c7t5000C500414FB2CFd0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c7t5000A7203006D81Ed0
在 mdb 调整后,注意 b% 列,80-85% 的时间处于繁忙等待状态
$ iostat -nx -M 5
r/s w/s Mr/s Mw/s wait actv wsvc_t asvc_t %w %b device
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t0d0
0.2 27.2 0.0 0.3 0.0 1.0 0.0 35.4 0 18 c0t395301D6B0C8069Ad0
129.6 20.2 0.9 0.4 0.0 2.9 0.0 19.5 0 85 c7t5000C500415DC933d0
48.4 4.0 0.4 0.0 0.0 0.0 0.0 0.1 0 1 c7t5000A72030068545d0
130.4 19.8 0.9 0.4 0.0 3.0 0.0 20.2 0 84 c7t5000C500415DC797d0
125.8 25.8 0.9 0.5 0.0 2.9 0.0 19.2 0 80 c7t5000C500414FCA57d0
131.2 24.2 0.9 0.5 0.0 3.1 0.0 20.3 0 83 c7t5000C500415C3B1Bd0
130.6 25.8 0.9 0.5 0.0 3.5 0.0 22.5 0 88 c7t5000C500415C5E4Fd0
126.8 28.0 0.9 0.5 0.0 2.8 0.0 18.0 0 79 c7t5000C500414FB2CFd0
0.2 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0 0 c7t5000A7203006D81Ed0
答案1
ZFS 清理操作遵循一些相当愚蠢的原则。最值得注意的是,它只在没有其他事情发生时才花时间进行清理。如果你经常用少量数据访问来戳一个池,清理实际上会让自己挨饿,几乎什么也不做。
可供探索的可调参数,以及我对其功能的简要说明(尽管我上次研究过这个问题已有一段时间了):
- zfs_scan_idle - 如果用户 I/O 发生在这么多时钟刻度内,则通过 zfs_scrub_delay 时钟刻度延迟清理 I/O
- zfs_scrub_delay - 如果由 zfs_scan_idle 触发,则延迟清理操作多少个时钟滴答
- zfs_top_maxinflight - 每个顶层 vdev 的最大清理 I/O 数量
- zfs_scrub_limit - 每个叶子 vdev 的最大清理 I/O 数量
- zfs_scan_min_time_ms - 每个 txg 在清理操作上花费的最小毫秒数
- zfs_no_scrub_io - 无注释
- zfs_no_scrub_prefetch - 没有注释,名称似乎暗示不会引起清理操作的预取
所有这些都可以使用“echo [tunable]/W0t[number]”随时更改,并使用“echo [tunable]/D”查看当前设置(我建议在更改之前这样做)。
因此,从理论上讲,在一般实践中,如果您要将 zfs_scan_idle 降至 10(或 1 - 或 0,如果它支持,则需要检查代码)并将 zfs_scrub_delay 降至 1(或 0,如果它支持),并且如果您的 txg_synctime_ms 设置是 5000 或更多,也许可以将 zfs_scan_min_time_ms 稍微调高一些,即使发生某种程度的用户 I/O,它也应该在实际执行清理操作方面变得更加积极。
在您的特定情况下,报告的 %b 和 asvc_t 暗示正在发生一些非常非常随机的读取工作负载(如果是真正连续的,旋转磁盘应该比这做得更好),并且您已经完成了上述“简单”的事情。因此,首先我会打开 zfs_no_scrub_prefetch,以禁用清理操作的预取,只是为了看看这是否有帮助。如果没有效果,则取决于您使用的 Nexenta 版本 - 您可能正在运行 30/5、5/1 或 10/5(这是我们用于 zfs_txg_timeout & (zfs_txg_synctime_ms*1000) 设置的简写)。将 zfs_txg_timeout 更改为 10,将 zfs_txg_synctime_ms 更改为 5000,然后尝试将 zfs_scan_min_time_ms 提高到 3000 或 4000。这会告诉 ZFS,与使用 5/1 作为默认值的旧 NexentaStor 安装中的默认设置相比,它可以在清理上花费更长的时间 - 但要小心,如果延迟设置也基本设置为 0,这可能会使正常 I/O 匮乏!
希望这有帮助,祝你好运!
答案2
我怀疑是硬件……
你为什么要让它运行 15 天?这不正常。停止清理 -zpool scrub -s tank
然后检查系统。
- 您正在使用哪种控制器?
- 这是你第一次在这个泳池里运行清理程序吗?
- 是否存在一个问题促使您首先运行清理?
答案3
我的回答有点晚了,但如果其他人也遇到这种情况,我的看法是:只需尝试“dmesg”。就我而言,我没有执行清理,而是将文件复制到磁盘,我清楚地听到磁盘活动了几秒钟,然后全部停止了很长时间,然后再次工作等等。这是由于一个 SATA 控制器出现故障,dmesg 向我提供了所有错误。我起初以为是磁盘出现故障,但后来我意识到实际上是控制器出现故障。
答案4
清理使用可用的系统停机时间,即使在未加载的服务器上,也与可用性有关。内存和处理器是清理利用率的关键,而不是磁盘。可用的内存和处理器越多,清理性能就越好。但是,当然,在这种情况下,就 ZPools 而言,磁盘布局越好,清理性能也会越好。
因此,如果您的表现一直很慢,而且确实如此,我会将这些视为潜在原因。