ZFS ARC 调优:上限、限制及需衡量的指标
11 分钟阅读 - 2026年6月24日

根据工作负载调整 ZFS ARC。哪些可调参数重要,如何在 Linux 和 FreeBSD 上设置 zfs_arc_max,以及如何判断调整是否完成。
默认情况下,ZFS 会悄无声息地占用系统约一半的 RAM 作为其读取缓存;若服务器配置不当,这将导致交换活动、OOM 进程终止,或数据库与文件系统争夺内存。ZFS ARC 调优的核心在于决定 ARC 实际被允许保留多少 RAM,以及为设定该限制需要做出哪些妥协。 本文将介绍 ARC 如何使用内存、在进行任何调整前应测量的指标、值得修改的几个可调参数,以及针对文件服务器、虚拟机管理程序、数据库和备份目标的合理起始配置。关于 ZFS 的快照功能,请参阅我们的 ZFS 快照指南。
在进行任何调整前,请先测量 ARC
在获得正常繁忙时段的基准数据之前,请勿更改任何可调参数。在非繁忙时段采集的数据会导致您误入歧途。夜间备份、每周报告和批处理作业通常是 ARC 行为表现得尤为显著的场景,因此请连续采集数天的数据。
以下三种工具可满足您的大部分需求:
arcstat 1可实时滚动显示命中与未命中计数器、需求与预取活动对比,以及当前 ARC 大小。请在负载测试和备份时段使用该工具。arc_summary可打印单次快照:ARC 大小和目标值、MFU/MRU 分布、元数据比例以及活跃的可调参数。仅针对 ARC 部分运行arc_summary -s arc仅用于查看ARC部分。- 原始计数器位于
/proc/spl/kstat/zfs/arcstats,在 Linux 系统中位于kstat.zfs.misc和vfs.zfssysctl树中。请从监控系统中提取这些数据,而非解析格式化后的输出。
在进行任何更改之前值得记录的计数器:
| 指标 | 查找位置 | 为何重要 |
|---|---|---|
ARC 大小、目标值、最大值 (size, c, c_max) | arcstat, kstat | 用于判断ARC是否已达到上限,还是仍有增长空间 |
| 需求数据和元数据命中率 | arcstat, arc_summary | 需求未满足会直接导致应用程序延迟 |
可用内存和交换活动 (si/so) | free -h, vmstat 1 | 当ARC较大时,持续的交换进出是内存压力的最明显迹象 |
磁盘服务时间(await)及利用率 | iostat -x | 将 ARC 缺失与实际存储瓶颈联系起来 |
memory_throttle_count | /proc/spl/kstat/zfs/arcstats | 计数值的上升证实 ZFS 正因内存压力而受到限速 |
人们在此常有两个误区。应关注可用内存,而非空闲内存;Linux 会将较低的空闲 RAM 视为稳定状态并如实报告,但这本身并不构成问题。 真正需要关注的信号是:可用内存接近零且伴随持续的交换活动(《Linux内存管理入门》中解释了原因)。此外,应将命中率视为一种趋势,而非目标。对于正在进行交换的系统而言,99%的命中率意味着调优失败,而非成功。
四个关键的 ARC 可调参数
大多数生产环境的调优归根结底取决于这四个设置。请根据基线测试中实际测得的压力值调整相应设置。交换活动指向 zfs_arc_max。回收因用户流失而不断清空热缓存的情况,则指向 zfs_arc_min。目录遍历速度过慢则指向元数据限制。
| 可调参数 | 作用 | 何时调整 | 设置错误的风险 |
|---|---|---|---|
zfs_arc_max | ARC RAM 使用的硬性上限 | 托管需要预留内存的数据库或虚拟机 | 过低:会导致更多磁盘I/O和延迟。过高:会导致交换压力或内存不足(OOM)。 |
zfs_arc_min | 防止ARC过度缩减的下限 | 存在短暂内存峰值且会不断清空缓存的工作负载 | 过高:在真正内存压力下会导致应用程序资源饥饿 |
zfs_arc_meta_limit_percent | 元数据可用的ARC比例(取代了旧的 zfs_arc_meta_limit) | 数百万个小文件、深层目录树、速度较慢 ls/find | 过低:目录查找速度极慢;过高:导致数据缓存资源不足。 |
zfs_arc_free_target | ZFS 试图保持多少可用系统内存 | 服务器出现突发的大量内存分配(虚拟机启动、大型查询计划) | 过高:即使有可用 RAM,ARC 仍保持较小 |
请从能解决当前可见压力的最小调整开始。对于 zfs_arc_max,合适的上限取决于工作负载(详见下一节)。对于 zfs_arc_min,若确实需要设定下限,则将 zfs_arc_max ,这已是一个合理的起点(若确实需要设定下限的话)。对于元数据,最新的 OpenZFS 默认设置已通过 zfs_arc_meta_limit_percent,这对大多数工作负载来说已经相当宽裕;只有当在 arcstat.
在 Linux 和 FreeBSD 上应用更改
在 Linux 上,可通过向 sysfs 参数文件写入内容来在运行时测试更改。无需重启:
echo 17179869184 > /sys/module/zfs/parameters/zfs_arc_max这将 zfs_arc_max 立即将该值设为 16 GiB。若要使该更改在重启后生效,请将其添加到 /etc/modprobe.d/zfs.conf:
options zfs zfs_arc_max=17179869184在 FreeBSD 上,运行时更改使用 sysctl:
sysctl vfs.zfs.arc_max=17179869184将相同值持久化到 /boot/loader.conf:
vfs.zfs.arc_max="17179869184"每次只更改一项设置,且调整幅度应控制在总内存的 10% 左右。密切关注问题窗口。仅当交换空间保持为零且延迟稳定时,才保留该更改。仅在运行时测试通过后才将其永久保存。
根据工作负载调整 ARC
仅考虑总内存容量并非正确的起点。ARC的配置应依据服务器上的工作负载组合来确定。
| 工作负载 | 启动 zfs_arc_max | ARC优先级 | 备注 | 关键指标 |
|---|---|---|---|---|
| 专用文件服务器/NAS | 75% 至 80% 的内存 | 数据和元数据 | 启用预读取。关键在于采用激进的缓存策略。 | 总体命中率 |
| 虚拟化主机 | 30% 至 40% 的 RAM | 平衡 | 为虚拟机内存和主机任务预留余量。任何非零 si/so 值则需进一步限制。 | 主机交换空间(si/so) |
| 数据库服务器 | 内存的25%至50% | 元数据密集型 | 首先为数据库引擎预留内存。设置 primarycache=metadata (如果该引擎自行管理缓冲区缓存)。 | 按需处理缓存未命中 |
| 备份/归档目标 | 保守上限 | 仅元数据 | 已设置 primarycache=metadata ,这样单次扫描就不会将有用的块驱逐出去。 | 预取未命中、元数据命中率 |
| 分析/重复读取 | 在预留其他缓存后提高上限 | MFU 密集型 | NVMe 上的 L2ARC 可在多次查询运行中保留热工作集。 | 按需访问未命中 |
由于虚拟机主机需要与虚拟机客户机共享内存,因此30%至40%的上限是一个安全的默认值,而在大多数构建环境中,50%的上限已经过高。PostgreSQL和MySQL等数据库会自行管理缓冲区缓存,因此应优先为引擎预留内存,剩余部分再分配给ARC。 备份目标可从中受益 primarycache=metadata ,因为被读取的数据很少会被再次使用,而且您不希望夜间备份在遍历整个池的同时,将缓存中的其余数据逐一清空。在所有工作负载中,当 ARC 被固定在 zfs_arc_max ,说明上限设置过高;这一规则始终不变。
故障诊断与适时停止
ARC 容量过小时,表现为读取 IOPS 值高、需求命中率低以及目录浏览缓慢,而系统仍拥有可用内存。ARC 容量过大则不太明显。命中率看似正常,但服务器开始进行交换,负载平均值攀升,进程在 D 状态,而内核则按需回收ARC页面;最坏的情况下,OOM杀手会开始选择“牺牲品”。缓存看似正常,但服务器运行状况却极差。
当 demand_metadata_bytes 远高于 demand_data_bytes 时 arc_summary。此时,元数据正与数据争夺空间,值得提高元数据百分比限制。
根据您观察到的现象,首先应检查以下设置:
| 症状 | 可能原因 | 首先应检查的配置项 | 下一步 |
|---|---|---|---|
高 await 伴随高需求缺失 | 工作集超过ARC | zfs_arc_max | 增加内存或增加 L2ARC |
| ARC 较大时的交换活动 | ARC 导致操作系统或应用程序资源不足 | zfs_arc_max | 降低上限 |
| 内存突增后性能骤降 | 回收期间发生激进的驱逐 | zfs_arc_min | 将下限设置为 arc_max |
慢 ls, find、小文件操作 | 元数据缓存饥饿 | zfs_arc_meta_limit_percent | 提高元数据占比 |
上升 memory_throttle_count | 全系统内存压力 | zfs_arc_max | 降低上限;检查 L2ARC 索引膨胀情况 |
L2ARC并非免费资源。L2ARC条目的索引存储在主ARC中,如果该开销超过ARC总容量的约三分之一,则二级缓存弊大于利。 仅当工作集大于内存容量但仍能容纳在高速 NVMe 设备上,且主 ARC 的命中率已处于健康水平时,才应启用 L2ARC。
停止调优的合适时机是:延迟趋于平稳,在引发原始问题的同一繁忙时段内交换量保持为零,且进一步调整已无法带来任何改善。如果服务器仍在进行交换,那么高命中率便毫无意义。达到这一阶段后,应停止调整设置,仅当在相同工作负载下问题再次出现时才重新审视这些设置。
如果您需要一台内存余量充足的服务器,以便在不与虚拟机或数据库争夺内存的情况下正常运行 ZFS(建议先阅读《您实际需要多少内存》一文),不妨关注 FDC 的专用服务器。

数字眼疲劳:在屏幕无处不在的世界中如何保护视力
整天盯着屏幕?了解如何通过行之有效的技巧和工具缓解数字眼疲劳。本指南对远程办公人员、开发人员以及所有科技从业者而言必不可少。
4 分钟阅读 - 2025年5月21日
为何拥有性能强劲且不限流量的 VPS 至关重要
8 分钟阅读 - 2025年5月9日