> For the complete documentation index, see [llms.txt](https://freebsd-journal-cn.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsd-journal-cn.bsdcn.org/20171112-jian-kong-yu-du-liang/monitoring-zfs.md).

# 监控 ZFS

作者：Allan Jude

ZFS 是先进的文件系统，也是最具可观察性的文件系统之一。ZFS 内置的静态和动态 DTrace 探针、统计信息以及工具组合，使其成为最容易分析性能的文件系统之一。本文介绍如何检查存储池健康度、实时测量负载与性能，以及如何用历史统计信息检测健康度、性能或行为上的变化。最后简要介绍其他可用于更深入监控系统的工具。

首先，存储池健康吗？

## 健康检查 • zpool status

`zpool status` 命令是评估存储池总体健康状况的首选之处。它会打印出池中设备布局的可视化表示以及每个设备的状态。除每个设备的状态外，还有计数器列，显示在每个设备上检测到的读、写和校验和错误次数。

每个设备可能处于以下状态之一：

* **Online** — 设备健康，按预期工作。
* **Offline** — 管理员已将该设备标记为离线。
* **Degraded** — 设备以降低的容量运行。通常只适用于顶层 vdev，如 RAID-Z 或 Mirror；表示一个或多个成员盘已发生故障，系统正利用校验信息维持运行。
* **Faulted** — 由于丢失过多数据，设备或池已无法工作。如果设备或池丢失的设备数超过其冗余度，文件可能无法访问或丢失。尝试重新连接缺失的设备以继续运行。
* **Removed** — 底层设备已被移除。这可能是磁盘故障后操作系统移除了设备，也可能是操作员物理断开了磁盘。
* **Missing** — ZFS 无法找到或无法打开该设备。尝试重新连接设备，或解决阻止 ZFS 打开设备的问题（例如被其他进程占用）。`zpool online` 命令可用于让设备重新上线。
* **Replacing** — 正在替换某设备。替换在线设备时，会创建一个名为 `replacing-X`（其中 X 为递增整数）的顶层 vdev；它实际上是一个镜像，新设备和旧设备都是其成员。数据从旧设备复制到新设备。
  * 操作完成后，旧设备会从池中分离，新设备成为 vdev 的普通成员。
* **Spare** — 设备缺失或处于降级状态，已用备件临时替换。
* **Resilvering** — 该设备曾临时离线或出现损坏，正从可用校验信息重建缺失或损坏的数据。

如果检测到池中存在一个或多个问题，状态输出末尾会显示一个摘要。运行 `zpool status -v <可选的池名>` 会扩展该摘要，并列出每个受损文件，便于从备份中恢复这些单独文件。

`zpool status` 命令还会跟踪 scrub 和 resilver 操作的进度，包括平均速度和完成预估。速度预估是整个操作的平均值，前几个百分比会非常慢，因此建议等到完成 5%–10% 后再认真看待速度和 ETA。如果系统在 resilver 操作期间重启或以其他方式中断，预估可能会长时间停留在 1 字节/秒。

## S.M.A.R.T.

磁盘还通过 SMART（自监测、分析和报告技术）协议提供一些关于其健康状态的洞察。对于机械磁盘，impending 失败的最佳指标通常是 pending 和 reallocated 扇区的数量。每个制造商提供不同的统计集合，因此很难制定关于什么状态意味着磁盘性能低下或潜在失效的硬性规则。

为了从 SMART 状态中的各种计数器中获取最大意义，你需要一个参照点——这些计数器过去是什么样、变化了多少、变化速度有多快。另一种需要注意的情况是循环计数高且快速增长。如果磁盘每隔几秒就休眠并唤醒一次，会对磁盘造成巨大磨损。可能需要给磁盘下达特定命令调整空闲超时，或更新固件来解决问题。SAS 磁盘提供的计数器通常较少，但在不同型号和制造商之间更一致。

SATA SSD 的 SMART 值通常有很大不同，因为许多常规值并不适用。大多数 SSD 会提供成对的计数器，记录已完成的读写总量，让管理员跟踪设备的磨损寿命。有些 SSD 还以百分比形式提供驱动器寿命统计，向设备有用寿命终点递增或递减。有时“原始值”（raw value）意义不大，需要查看‘value’和‘thresh(old)’值。下面这块 SSD 的磨损相对较小。

## 交互式性能监控

确认池健康后，接下来看池正在发生什么。这些交互式监控工具可以揭示实时进行的操作。

### zpool iostat

`zpool iostat` 命令会打印池上的活动数据。它显示读写 IOPS 数以及每秒字节数。如果不给其他参数，它会为每个池显示一行状态。如果给出池名，则只显示该池。如果给出一个整数，它会持续运行，每 X 秒打印新统计，X 即该整数。你会注意到 ZFS 的自然周期：应用程序请求的同步写操作数量最少；然后每 5 秒所有其他缓冲的异步写操作会被刷到磁盘。如果将整数改为更长间隔，它会提供该时间段内的平均值。

### top -m io

找出哪个应用程序在产生所有 I/O 的最快方法之一是使用 top。FreeBSD 的 top 有标志 `-m` 用于切换模式。在 IO 模式下，它不再按 CPU 和内存使用情况跟踪应用程序，而是按读、写和其他 IO 操作跟踪。这有助于判断哪个应用程序在消耗所有 IO 资源。要进一步细分，请参见下文 DTrace Toolkit 部分。

### zfs-stats

在 Solaris 上，ZFS 使用一个名为 kstat 的系统来发布关于 ZFS 内部运作的各种统计信息。在 FreeBSD 上，这些统计通过 sysctl 接口发布。`sysutils/zfs-stats` 软件包可以用更易读的方式汇总这些统计信息，并将它们按逻辑分组。

## 内存节流

更重要的问题指标是“Memory Throttle Count”（内存节流计数）。这是 ZFS ARC 因系统中其他地方的内存需求而不得不减少其内存使用次数。你可以考虑将 ARC 的最大大小（`vfs.zfs.arc_max`）设为使 ZFS 与其他工作负载更好共存的值。输出还显示按 MRU（最近最少使用）和 MFU（最频繁使用）细分的 ARC 使用情况。这让你了解缓存如何适应工作负载。

### zfs-mon

`sysutils/zfs-stats` 软件包还包含第二个工具 `zfs-mon`，它观察一部分 kstats 随时间的变化。这能为请求如何分解以及 ZFS 中各种缓存层如何被使用提供有用洞察。统计信息细分了 ARC、L2ARC、文件系统预取和设备预取代码的性能。它还细分为数据操作与元数据操作。默认情况下，ZFS 将可用于元数据的缓存量限制为最大 ARC 大小的 25%。如果总存储容量非常大——而且大多数操作只影响文件的元数据而非内容——增加可用于元数据的 ARC 量实际上能提升性能，否则 ARC 可能 3/4 充满再也不会被引用的内容，直到被其他内容替换。

如你所见，ARC 缓存命中率在短间隔内变化很大，但在这工具运行的 5 分半钟内，总体平均命中率为 95.29%。

## GEOM 统计

`gstat` 是交互式工具，从 FreeBSD GEOM 子系统拉取统计信息。它可以是观察底层存储所发生情况的有用窗口。对于每个 GEOM 对象（可能有许多代表单个设备、分区或设备的其他细分），它会打印队列深度、每秒总操作数、每秒读操作数、每秒读千字节数、每次读操作毫秒数，以及写操作的所有这些相同指标。然后会计算合成的‘% busy’数值，这只是一个最佳猜测，常常会超过 100%。还有其他操作类型（delete 用于 TRIM/UNMAP 等，以及 flush），可通过附加标志显示。如果每秒读写 IOPS 之和小于 ops/s 列中的值，很可能也在发生这些其他操作。

## DTrace Toolkit

DTrace 是非常强大的工具，旨在让你安全地检查和调试运行中的系统，且在不调试时对性能的影响极小。DTrace 脚本的复杂程度差异很大，从简单的一行命令到交互式工具都有。

一个 DTrace 一行命令的简单示例：

这会按调用应用程序的名称对 read 系统调用的第三个参数（参数从 0 开始编号）创建聚合。运行几秒钟，然后按 control+c 停止。它会打印出每个调用 read 的应用程序及其读取的总字节数列表。现在就能明显看出是哪个应用程序在产生所有磁盘读取了。

你不必自己编写 DTrace 脚本；OpenDTrace 项目维护着一批跨平台脚本，可供下载使用。它们是很好的起点，可以修改以回答你想问的问题；<https://github.com/opendtrace/toolkit>

要查看每个事务组写入多少数据，或每个事务组同步到磁盘耗时多久，可查看 Adam Leventhal 的这些 DTrace 示例：<http://dtrace.org/blogs/ahl/2014/08/31/openzfs-tuning/>

## 持续性能监控

理解性能问题的原因首先需要有可对比新测量和观察结果的参照。当前每秒操作数水平是否典型？还是远高于或低于预期？要理解缓存命中率，你需要知道系统没有问题时它是什么样。要拥有并能理解这些信息，你需要持续记录你想用来与系统当前状态对比的指标。以有用方式收集、存储和绘制这些指标，是快速诊断问题并及早发现问题的关键。

磁盘故障时往往不那么“绅士”。它们不会彻底死亡并完全离线，而常常表现异常。磁盘开始失效的最早迹象之一，可能是读写延迟大幅增加。消费级磁盘在返回读错误前常常内部重试多次。操作系统随后可能又会“好心”让驱动器再重试几次，这些重复命令中的每一次都会导致一系列额外的内部重试。正因如此，操作系统在等待命令完成时往往会有相当高的超时，默认值约为每条命令 30 秒、重试 5 次。一次失败的读取因此可能拖住整个系统长达 2 分半钟。

## ZFS KSTATS

ZFS 通过 kstat 接口提供了数量可观的统计信息和计数器。在 FreeBSD 上，目前通过 `kstats.zfs` sysctl mib 暴露这些信息。

ZFS 的优势之一是 ARC（自适应替换缓存），它提供的缓存命中率优于标准 LRU（最近最少使用）缓存。查看有关 ARC 的各种统计信息可以洞察系统正在发生什么。

* `kstat.zfs.misc.arcstats.c_max` — ARC 的目标最大大小。
* `kstat.zfs.misc.arcstats.c_min` — ARC 的目标最小大小。ARC 不会缩小到低于此大小，虽然可以用 `vfs.zfs.arc_min` sysctl 调整。
* `kstat.zfs.misc.arcstats.size` — ARC 的当前大小；如果小于最大值，说明你的系统要么没有足够活动填满 ARC，要么来自其他进程的内存压力导致 ARC 缩小。
* `kstat.zfs.misc.arcstats.c` — ARC 的当前目标大小。如果 ARC 的当前大小小于此值，ARC 会尝试增长。
* `kstat.zfs.misc.arcstats.p` — 多少 ARC 用于 MRU 列表；其余是 MFU 列表的目标。此值会根据工作负载动态调整。较低的值表明频繁访问相同块，较高的值表明更多样的工作负载。
* `kstat.zfs.misc.arcstats.arc_meta_used` — 用于存储元数据而非用户数据的 ARC 量。如果此值已达到 `vfs.zfs.arc_meta_limit`（默认为 `vfs.zfs.arc_max` 的 25%），则考虑提高或降低用于元数据的 ARC 比例。缓存更多元数据会加快目录扫描和其他操作，代价是减少可缓存的用户数据量。

## SNMP

`net-snmpd` 提供许多有用的计数器，例如每台设备的总 IOPS、读写字节数。这些可以用来创建图形，在排查性能问题时提供历史视角。IOPS 负载是平常的两倍吗？那可能就是你的问题。如果 IOPS 数量下降，但工作负载更高，可能有什么因素导致一台或多台设备性能欠佳。

## 其他工具

有许多不同的解决方案用于监控、测量和记录系统统计信息。你可能想要研究的包括：

* **Zabbix** — 一套高级监控套件，带有一些预定义的 ZFS 探针。
* **Collectd** — 一个指标收集守护进程，可与多种不同后端配合使用。
* **Grafana** — 一款时序数据图形与分析工具，能为 collectd 等应用收集的指标赋予意义。
* **OSQuery** — 操作系统监测框架，使用熟悉的结构化查询语言分析系统的实时和历史指标。•

***

> **ALLAN JUDE** 是 ScaleEngine Inc.（全球 HTTP 和视频流内容分发网络）的运营副总裁，他在 FreeBSD 上大量使用 ZFS。Allan 是 FreeBSD src 和 doc 提交者，于 2016 年夏当选 FreeBSD core team 成员。他也是每周视频播客 BSDNow\.tv（与 Benedict Reuschling 共同主持）的主持人，并与 Michael W Lucas 合著了《FreeBSD Mastery: ZFS》和《FreeBSD Mastery: Advanced ZFS》。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://freebsd-journal-cn.bsdcn.org/20171112-jian-kong-yu-du-liang/monitoring-zfs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
