在 Solaris 11.1 安装中,我在接收 zfs 增量流时看到停顿。这些流源自 Solaris 11.0 安装,使用 创建zfs send -i
并通过管道传输mbuffer
。在某个时间点,我偶尔会看到写入性能停顿(目标磁盘上几乎没有读取或写入活动,mpstat
报告相同或不同核心的利用率总计略高于“系统”的 100%,其他负载为 0):
root@receiver:~# mpstat 5
[...]
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 363 103 213 0 9 4 0 14 0 6 0 94
1 0 0 0 113 3 149 0 11 6 0 16 0 12 0 88
2 1 0 2 40 4 36 0 9 5 0 3 0 1 0 99
3 0 0 0 82 59 18 0 2 3 0 3 0 93 0 7
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 3 0 0 362 104 207 0 9 6 0 12 0 14 0 86
1 0 0 0 90 4 109 0 10 7 0 3 0 17 0 83
2 0 0 0 48 2 40 0 9 3 0 5 0 10 0 90
3 0 0 0 100 54 44 0 7 3 0 4 0 69 0 31
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 332 103 35 0 6 3 0 0 0 45 0 55
1 0 0 0 27 3 22 0 3 1 0 0 0 45 0 55
2 0 0 0 142 3 172 0 9 6 0 4 0 18 0 82
3 0 0 0 181 56 178 0 10 6 0 8 0 1 0 99
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 327 103 54 0 5 2 0 2 0 49 0 51
1 0 0 0 46 3 52 0 9 3 0 0 0 28 0 72
2 0 0 0 156 2 175 0 9 5 0 4 0 25 0 75
3 0 0 0 153 62 132 1 8 6 0 5 0 3 0 97
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 1 380 103 164 0 11 9 0 7 0 5 0 95
1 0 0 0 144 3 165 0 11 9 0 6 0 25 0 75
2 0 0 0 39 1 36 0 6 4 0 2 0 66 0 34
3 0 0 0 125 77 55 0 10 6 0 1 0 14 0 86
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 372 107 178 0 9 9 0 19 0 3 0 97
1 0 0 0 145 3 193 0 9 10 0 8 0 8 0 92
2 0 0 0 24 2 26 0 9 3 0 0 0 2 0 98
3 0 0 0 94 86 3 0 0 5 0 0 0 100 0 0
在又突发写入 200-300 MB 之后,传输几乎停止了:
root@receiver:~# zpool iostat tank 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.85T 2.01T 511 831 7.76M 4.60M
tank 1.85T 2.01T 0 26 0 65.4K
tank 1.85T 2.01T 3 25 13.2K 62.4K
tank 1.85T 2.01T 4 34 5.00K 76.2K
tank 1.85T 2.01T 3 32 3.10K 87.0K
tank 1.85T 2.01T 0 25 1.20K 59.0K
tank 1.85T 2.01T 6 58 4.30K 339K
tank 1.85T 2.01T 1 28 3.70K 63.1K
tank 1.85T 2.01T 19 30 36.9K 83.2K
并且接收端和发送端的 mbuffers 利用率都是 100%。
这似乎只发生在较大的 (> 5G) 快照中,我确实看到在流末尾出现停顿,在前几 GB 在合理的时间内成功传输之后。流接收仍在工作,只是非常缓慢 - 数据速率低于 100 KB/s(从接收端mbuffer
的内存到空闲磁盘)。
我也尝试过将 mbuffer 从方程式中移除,并zfs send
通过 SSH 将流直接传输到zfs receive
,但似乎没有什么显著的不同。快照最终会被传输,但最后 1-2 GB 需要几个小时。
接收主机完全处于空闲状态,此时控制台、内核消息日志或 /var/log/syslog 中不会打印任何消息。目标 zpool 仍然可用 - 我仍然可以随时访问位于同一 zpool 中的其他文件系统。此外,以线速接收数百 GB 大小的完整、非增量/非递归 zfs 流,没有任何明显的问题。
11.1 中是否存在与此问题相关的已知问题?当接收器应写入流时,如何进一步诊断接收器正在等待什么?
答案1
当您像这样将 zfs send 和 zfs accept 管道连接在一起时,它们会相互关联。源系统必须抓取 zfs 元数据,以查找在您发送的增量间隔内写入的块。然后,您将其管道传输到 mbuffer,这样就可以通过在两端呈现一个可以缓解停顿和超限的存储桶来优化 ssh 会话中的流。然后,来自 mbuffer 的管道将数据馈送到 zfs 接收,后者必须像处理写入数据一样处理传入的数据。因此,每个事务组有 X 个事务,刷新到磁盘,计算元数据,并将其全部写出,一直到超级块。这看起来很像流中的停顿,通常可持续 5 到 30 秒。如果吞吐量下降持续时间超过 30 秒,则可能是某个地方的资源受限。
例如,根据您的系统调整方式,您是否拥有快速的 ZIL SLOG?或者,您的 zpool 后面是否有大量主轴来优化 logbias=throughput?根据此类问题的答案,您将能够确定您是否在某个地方受到资源限制。
您的 CPU 看起来没有受到太大影响。我每天都会看到 ZPOOL 大小为 250+TB 的服务器,其mpstat
intr
列数超过 20,000。更多的 CPU 总是会提高 mpstat 数字。
我会查看一些 dtrace 脚本,例如zilstat
、、arcstat
等iopattern
(检查 DtraceToolkit)以查看系统在您暂停期间正在做什么。