ZFS 执行 2 种类型的读取缓存
- ARC(自适应替换缓存):
ZFS 将最近和最常访问的文件缓存在 RAM 中。一旦文件缓存在内存上,下次访问同一文件时,将从缓存而不是慢速硬盘中提供该文件。访问这些缓存文件将比从硬盘访问它们快很多倍。
- L2ARC(2 级自适应替换缓存):
ARC 缓存存储在计算机内存中。当内存已满时,最旧的数据将从 ARC 缓存中删除,并缓存新数据。如果您不希望 ZFS 永久丢弃缓存的数据,您可以将快速 SSD 配置为 ZFS 池的 L2ARC 缓存。
为 ZFS 池配置 L2ARC 缓存后,ZFS 将从 ARC 缓存中删除的数据存储在 L2ARC 缓存中。因此,可以在缓存中保存更多数据以便更快地访问。
ZFS 执行 2 种类型的写入缓存
- ZIL(ZFS 意图日志):
默认情况下,ZFS 分配池的一小部分用于存储写入缓存。它称为 ZIL 或 ZFS 意图日志。在数据写入物理硬盘之前,数据存储在 ZIL 中。为了最大限度地减少写入操作的数量并减少数据碎片,数据会被分组到 ZIL 中,并在达到某个阈值后刷新到物理硬盘驱动器。它更像是一个写缓冲区而不是缓存。你可以这样想。
- SLOG(辅助日志):
由于 ZFS 使用池的一小部分来存储 ZIL,因此它共享 ZFS 池的带宽。这可能会对 ZFS 池的性能产生负面影响。
要解决此问题,您可以使用快速 SSD 作为 SLOG 设备。如果 ZFS 池上存在 SLOG 设备,则 ZIL 将移动到 SLOG 设备。 ZFS 将不再在池中存储 ZIL 数据。因此,ZIL 上不会浪费任何池带宽。
还有其他好处。如果应用程序通过网络(即 VMware ESXi、NFS)写入 ZFS 池,ZFS 可以快速将数据写入 SLOG 并向应用程序发送数据已写入磁盘的确认。然后,它可以像往常一样将数据写入速度较慢的硬盘。这将使这些应用程序的响应速度更快。
请注意,通常情况下,ZFS 不会从 SLOG 中读取。 ZFS 仅在断电或写入失败时从 SLOG 读取数据。已确认的写入仅暂时存储在那里,直到它们被刷新到较慢的硬盘驱动器。它只是为了确保在断电或写入失败的情况下,已确认的写入不会丢失,并且它们会尽快刷新到永久存储设备。
另请注意,在没有 SLOG 设备的情况下,ZIL 将用于相同目的。
现在您已经了解了有关 ZFS 读取和写入缓存的所有信息,让我们看看如何在 ZFS 池上配置它们。
配置 ARC 最大内存限制
在 Linux 上,ZFS 默认使用 50% 的已安装内存用于 ARC 缓存。因此,如果您的计算机上安装了 8 GB 内存,ZFS 最多将使用 4 GB 内存进行 ARC 缓存。
如果需要,您可以增加或减少 ZFS 可用于 ARC 缓存的最大内存量。要设置 ZFS 可用于 ARC 缓存的最大内存量,可以使用 zfs_arc_max 内核参数。
通过arc_summary命令可以找到很多ARC缓存的使用信息,如下:
sudo arc_summary -s arc
在ARC size (current)部分,可以找到ARC缓存可以增长的最大大小(Max size (high water)),即当前ARC的大小缓存(目标大小(自适应))以及其他 ARC 缓存使用信息,如下面的屏幕截图所示。
请注意,我的计算机上的最大 ARC 缓存大小为 3.9 GB,因为我的计算机上安装了 8 GB 内存。正如我之前提到的,这大约是总可用内存的 50%。
您可以看到有多少数据命中了 ARC 缓存以及有多少数据未命中 ARC 缓存。这可以帮助您确定 ARC 缓存在您的场景中的工作效率。
要打印 ARC 缓存命中/未命中的摘要,请运行以下命令:
sudo arc_summary -s archits
应显示 ARC 缓存命中和未命中的摘要,如下面的屏幕截图所示。
您可以使用以下命令监控 ZFS ARC 缓存的内存使用情况:
sudo arcstat 1 2>/dev/null
可以看到,最大ARC缓存内存(c)、当前ARC缓存大小(arcsz)、从ARC缓存读取的数据(read)强>)等信息显示。
现在,让我们看看如何为 ZFS ARC 缓存设置自定义内存限制。
要为 ZFS ARC 缓存设置自定义最大内存限制,请在 /etc/modprobe.d/ 目录中创建一个新文件 zfs.conf,如下所示:
sudo nano /etc/modprobe.d/zfs.conf
在 zfs.conf 文件中输入以下行:
options zfs zfs_arc_max=<memory_size_in_bytes>
将 替换为您所需的 ZFS ARC 缓存最大内存限制(以字节为单位)。
假设您想要为 ZFS ARC 缓存使用 5 GB 内存。要将 5 GB 转换为字节,可以使用以下命令:
echo $((5 * 2**30))
如您所见,5 GB 等于 5368709120 字节。
您可以使用 Python 3 解释器执行相同的操作,如下所示:
python3 -c "print(5 * 2**30)"
设置 ZFS ARC 缓存最大内存限制后,按 + X,然后按 Y 和 保存 zfs.conf 文件。
现在,使用以下命令更新当前内核的 initramfs 映像:
sudo update-initramfs -u
应更新 initramfs 映像。
为了使更改生效,请使用以下命令重新启动计算机:
sudo reboot
下次启动计算机时,ZFS ARC 缓存的最大内存限制应设置为您所需的大小(在我的情况下为 5 GB),如下面的屏幕截图所示。
sudo arc_summary -s arc
添加 L2ARC 缓存设备
如果将 L2ARC 缓存设备(SSD 或 NVME SSD)添加到 ZFS 池,则当内存已满(或达到最大 ARC 限制)时,ZFS 会将 ARC 缓存卸载(移动)到 L2ARC 设备。因此,可以在缓存中保存更多数据,以便更快地访问 ZFS 池。
现在,假设您想要添加 NVME SSD nvme0n1 作为 ZFS 池 pool1 的 L2ARC 缓存设备。
sudo lsblk
要将 NVME SSD nvme0n1 添加到 ZFS 池 pool1 作为 L2ARC 缓存设备,请运行以下命令:
sudo zpool add -f hdd-st4000 cache /dev/nvme0n1
# zpool add -f hdd-st4000 cache /dev/nvme0n1
ssd 已经作为 L2ARC 缓存设备添加到 ZFS 池 hdd-st4000 中
# zpool status
pool: hdd-st4000
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
hdd-st4000 ONLINE 0 0 0
ata-ST4000VX016-3CV104_WW629X5Q ONLINE 0 0 0
cache
nvme0n1 ONLINE 0 0 0
errors: No known data errors
用zpool iostat -v可以明显看到SSD的读写缓存已经生效了,后续热文件将直接从cache中读取,降低机械盘的负载。
# zpool iostat -v
capacity operations bandwidth
pool alloc free read write read write
--------------------------------- ----- ----- ----- ----- ----- -----
hdd-st4000 104G 3.52T 11 19 3.58M 15.5M
ata-ST4000VX016-3CV104_WW629X5Q 104G 3.52T 11 19 3.58M 15.5M
cache - - - - - -
nvme0n1 56.8G 420G 44 120 5.54M 14.8M
--------------------------------- ----- ----- ----- ----- ----- -----
将 L2ARC 缓存设备添加到 ZFS 池后,您可以使用 arc_summary 命令显示 L2ARC 缓存统计信息,如下所示:
# sudo arc_summary -s l2arc
------------------------------------------------------------------------
ZFS Subsystem Report Thu Jul 18 15:06:04 2024
Linux 6.8.8-2-pve 2.2.4-pve1
Machine: pve (x86_64) 2.2.4-pve1
L2ARC status: HEALTHY
Low memory aborts: 0
Free on write: 0
R/W clashes: 0
Bad checksums: 0
Read errors: 0
Write errors: 0
L2ARC size (adaptive): 882.3 MiB
Compressed: 16.4 % 144.9 MiB
Header size: 0.0 % 0 Bytes
MFU allocated size: < 0.1 % 4.0 KiB
MRU allocated size: 100.0 % 144.9 MiB
Prefetch allocated size: 0.0 % 0 Bytes
Data (buffer content) allocated size: 98.5 % 142.7 MiB
Metadata (buffer content) allocated size: 1.5 % 2.2 MiB
L2ARC breakdown: 0
Hit ratio: n/a 0
Miss ratio: n/a 0
L2ARC I/O:
Reads: 0 Bytes 0
Writes: 145.0 MiB 19
L2ARC evicts:
L1 cached: 0
While reading: 0
log: 也称 slog ,ZFS 的写缓存,加速 同步 写入
- 注意!slog 只影响同步写入,异步写入(比如拷贝文件)是不受影响的。一般只有非常关键的数据会要求同步写入(例如数据库程序)
- 因此,如果你的工况不涉及同步写入的话,添加此种缓存也 可能完全不会提升性能
添加 SLOG 设备
您可以在 ZFS 池上添加一个或多个 SSD/NVME SSD 作为 SLOG(辅助日志)设备,以在其中存储 ZFS 池的 ZFS 意图日志 (ZIL)。
通常添加一个 SSD 就足够了。但由于 SLOG 用于确保在发生电源故障和其他写入问题时写入不会丢失,因此建议在镜像配置中使用 2 个 SSD。这将为您提供更多保护并确保不会丢失任何写入内容。
假设您想要将 NVME SSD nvme0n2 和 nvme0n3 添加为镜像配置中 ZFS 池 pool1 上的 SLOG 设备。
sudo lsblk -e7
要将 NVME SSD nvme0n2 和 nvme0n3 添加为镜像配置中 ZFS 池 pool1 上的 SLOG 设备,请运行以下命令:
$ sudo zpool add -f pool1 log mirror /dev/nvme0n2 /dev/nvme0n3
如果您想要在 ZFS 池 pool1 上添加单个 NVME SSD nvme0n2 作为 SLOG 设备,您可以运行以下命令:
sudo zpool add -f pool1 log /dev/nvme0n2
NVME SSD nvme0n2 和 nvme0n3 应作为镜像模式下的 SLOG 设备添加到您的 ZFS 池 pool1 中,如下面的屏幕截图所示。
sudo zpool status pool1
您可以使用arc_summary命令查找ZIL和SLOG交易信息,如下所示:
sudo arc_summary -s zil
应显示 ZIL 和 SLOG 事务信息,如下面的屏幕截图所示。
结论
在本文中,我讨论了 ZFS 文件系统的不同类型的读写缓存功能。我还向您展示了如何配置 ARC 缓存的内存限制。我还向您展示了如何将 L2ARC 缓存设备和 SLOG 设备添加到 ZFS 池。
参考文献
https://cn.linux-console.net/?p=15715
删除缓存
-
命令
# 删除cache zpool remove pool-name cache-name # 删除log zpool remove pool-name log-name
-
实例
zpool status pool: hdd-st4000 state: DEGRADED status: One or more devices could not be used because the label is missing or invalid. Sufficient replicas exist for the pool to continue functioning in a degraded state. action: Replace the device using 'zpool replace'. see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-4J scan: scrub repaired 0B in 00:26:33 with 0 errors on Sun Sep 8 00:50:34 2024 config: NAME STATE READ WRITE CKSUM hdd-st4000 DEGRADED 0 0 0 ata-ST4000VX016-3CV104_WW629X5Q DEGRADED 0 0 0 too many errors cache nvme-eui.0025388a81010ec1 UNAVAIL 0 0 0 errors: No known data errors root@pve:/hdd-st4000/fio-test# zpool remove hdd-st4000 nvme-eui.0025388a81010ec1 root@pve:/hdd-st4000/fio-test# zpool status pool: hdd-st4000 state: DEGRADED status: One or more devices has experienced an unrecoverable error. An attempt was made to correct the error. Applications are unaffected. action: Determine if the device needs to be replaced, and clear the errors using 'zpool clear' or replace the device with 'zpool replace'. see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P scan: scrub repaired 0B in 00:26:33 with 0 errors on Sun Sep 8 00:50:34 2024 config: NAME STATE READ WRITE CKSUM hdd-st4000 DEGRADED 0 0 0 ata-ST4000VX016-3CV104_WW629X5Q DEGRADED 0 0 0 too many errors errors: No known data errors