Ubuntu 20.04 上的 ZFS 是否使用了大量内存?

Tho*_*wne 9 ram zfs 20.04

我安装了 64GB,但 htop 显示 20GB 正在使用中:

在此处输入图片说明

运行ps aux | awk '{print $6/1024 " MB\t\t" $11}' | sort -n为我提供了仅使用 100 兆字节的最大进程,并且将整个输出加起来只能得到 2.8GB ( ps aux | awk '{print $6/1024}' | paste -s -d+ - | bc)。这或多或少是我在昨天升级的 Ubuntu 19.04 中得到的 - 没有应用程序运行时使用了 3GB 到 4GB。那么为什么在 htop 上使用 20GB 呢?

现在确实我已经安装了 ZFS(总共 1.5 GB 的 SSD 驱动器,在 3 个池中,其中一个是压缩的),并且我一直在移动一些非常大的文件,以便我可以了解是否有一些缓存分配。htop Mem 栏大部分是绿色的,这意味着“正在使用的内存”,而不是缓冲区(蓝色)或缓存(橙色),因此非常令人担忧。

这个 ZFS 是否使用了大量 RAM,如果是这样,如果其他应用程序需要它,它会释放一些吗?

编辑

这是 smem 的输出:

tbrowne@RyVe:~$ smem -tw
Area                           Used      Cache   Noncache 
firmware/hardware                 0          0          0 
kernel image                      0          0          0 
kernel dynamic memory      20762532     435044   20327488 
userspace memory            2290448     519736    1770712 
free memory                42823220   42823220          0 
----------------------------------------------------------
                           65876200   43778000   22098200 
Run Code Online (Sandbox Code Playgroud)

因此,罪魁祸首是“内核动态内存”。为什么这么多?

编辑 2 --> 似乎与巨大的文件创建有关

我重新启动,RAM 使用量约为 5GB。甚至在 firefox 中运行一堆标签,运行几个虚拟机,将 RAM 增加到 20GB,然后关闭所有应用程序,它回落到 5GB。然后我在 Python 中创建了一个大文件(1.8G 的随机数 CSV),然后将其连接到自身 40 倍以生成一个 72GB 的文件:

tbrowne@RyVe:~$ python3
Python 3.8.2 (default, Mar 13 2020, 10:14:16) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> import pandas as pd
>>> pd.DataFrame(np.random.rand(10000, 10000)).to_csv("bigrand.csv")
>>> quit()
tbrowne@RyVe:~$ for i in {1..40}; do cat bigrand.csv >> biggest.csv; done
Run Code Online (Sandbox Code Playgroud)

现在一切都完成了,机器上没有任何运行,我有 34G 正在被内核使用!

在此处输入图片说明

最终编辑(测试答案)

这个 python 3 脚本(你需要 pip3 install numpy)将一次分配大约 1GB 直到它失败。根据下面的答案,只要您运行它,内核内存就会被释放,因此我能够在它被杀死之前分配 64 GB(我的交换空间很少)。换句话说,它确认 ZFS 将在需要时释放内存。

import numpy as np
xx = np.random.rand(10000, 12500)
import sys
sys.getsizeof(xx)
# 1000000112
# that's about 1 GB
ll = []
index = 1
while True:
    print(index)
    ll.append(np.random.rand(10000, 12500))
    index = index + 1
Run Code Online (Sandbox Code Playgroud)

Col*_*ing 20

ZFS 将缓存数据和元数据,因此 ZFS 将使用大量可用内存。当内存压力开始出现时(例如,加载需要大量页面的程序)缓存数据将被逐出。如果您有大量空闲内存,它将被用作缓存,直到需要为止。

可以使用arc_summary工具查看ZFS ARC(自适应替换缓存)使用的资源

  • 请注意,这实际上与普通文件系统没有太大区别。差异在于 ZFS 使用它自己的缓存而不是 Linux VFS 层提供的缓存,这意味着它在 Linux 上的大多数工具中以不同的方式报告。 (10认同)
  • 确实很有趣。arc_summary 输出中的“ARC 大小(当前)”显示最小大小为 2.0 GiB,最大大小为 31.4 GiB。我的目标大小(自适应)显示相同的 31.4GB。看,我很高兴它尽可能多地使用我的大块空闲内存,因为它想加快速度 - 这是积极的,只要我知道它稍后会归还!所以是的,这个 arc_summary 工具回答了我的问题。我恐慌了几个小时,因为我在任何地方(包括引导)都使用“实验性”ZFS 将信封推得太远了。也就是说,我已经将两个 SSD 合并到一个池中,我喜欢它! (2认同)
  • @ThomasBrowne 哦,它已经因占用内存而闻名,因为人们没有研究为什么数字是这样的(当然,在某些配置中实际上需要非常大量的内存)。不幸的是,这不是现实中可以解决的问题,因为这样做需要将 Linux 上的 ZFS 合并到主线内核存储库中,出于许可原因,这在法律上是不合法的(CDDL 与 GPL 不兼容)。 (2认同)

max*_*max 5

默认情况下,Ubuntu 20.04 上最多 50% 的系统 RAM 分配给 ZFS。如果其他进程需要,ZFS 会释放 RAM,但这需要一些时间。例如,我因此在 Virtualbox 虚拟机上尝试了一些冻结。

如果您无法升级 RAM,一个简单的解决方案是限制 ZFS 使用的 RAM。首先检查当前分配了多少arc_summary

  • 最小大小(硬限制)= 分配的最小大小
  • 最大尺寸(高水位)= 分配的最大尺寸

值以位表示,但您可以在http://www.matisse.net/bitcalc/?input_amount=3&input_units=gigabits¬ation=legacy进行转换

然后:

  • sudo nano /etc/modprobe.d/zfs.conf(如果文件不存在则正常)
  • 添加options zfs zfs_arc_max=3221225472(例如设置 3 GB 限制)
  • 保存并退出
  • sudo update-initramfs -u
  • sudo reboot

希望能帮助到你!