Dav*_*get 11 linux memory-management zfs lxc
我的Ubuntu 12服务器神秘地丢失/浪费内存.它有64GB的内存.即使我关闭了所有应用程序,也会显示大约46GB.不报告此内存用于缓冲区或缓存.
顶部的结果(我的应用程序正在运行;应用程序使用大约9G):
top - 21:22:48 up 46 days, 10:12, 1 user, load average: 0.01, 0.09, 0.12
Tasks: 635 total, 1 running, 633 sleeping, 1 stopped, 0 zombie
Cpu(s): 0.2%us, 0.2%sy, 0.0%ni, 99.6%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 65960100k total, 55038076k used, 10922024k free, 271700k buffers
Swap: 0k total, 0k used, 0k free, 4860768k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5303 1002 20 0 26.2g 1.2g 12m S 0 1.8 2:08.21 java
5263 1003 20 0 9.8g 995m 4544 S 0 1.5 0:19.82 mysqld
7021 www-data 20 0 3780m 18m 2460 S 0 0.0 8:37.50 apache2
7022 www-data 20 0 3780m 18m 2540 S 0 0.0 8:38.28 apache2
.... (smaller processes)
Run Code Online (Sandbox Code Playgroud)
请注意,top报告4.8G用于缓存,而不是48G,并且它使用的是55G.free -m的结果:
total used free shared buffers cached
Mem: 64414 53747 10666 0 265 4746
-/+ buffers/cache: 48735 15678
Swap: 0 0 0
Run Code Online (Sandbox Code Playgroud)
什么在用我的记忆?我已经尝试了每一种我都能遇到的诊断.论坛淹没了人们问同样的问题,因为Linux正在使用他们的RAM用于缓冲区/缓存.这似乎不是这里发生的事情.
系统是lxc容器的主机可能是相关的.上面报告的最高和免费结果来自主机,但容器内报告了类似的内存使用情况.停止所有容器不会释放内存.一些46G仍在使用中.但是,如果我重新启动主机,内存是免费的.它不会在一段时间内达到46G.(我不知道是否需要数天或数周.这需要几个小时.)
系统使用zfs也可能是相关的.Zfs在内存方面很受欢迎,但并不是那么多.该系统在两个raidz池上有两个zfs文件系统,一个是1.5T,另一个是200G.我有另一台服务器,它表现出完全相同的问题(没有使用46G)并且配置非常相同,但使用3T阵列而不是1.5T.我为每个zfs文件系统提供了大量快照(大约100个).我通常有一个随时安装的每个文件系统的快照.卸下那些并没有让我回忆起我的记忆.
我可以看到上面屏幕截图中的VIRT数字大致与使用的内存大致相符,但即使在我关闭运行它们的容器后,即使我关闭这些应用程序后内存仍然使用.
编辑:我尝试添加一些交换,发生了一些有趣的事情.我添加了30G的交换.片刻之后,标记为缓存在顶部的内存量从5G增加到25G.Free -m表示大约20G可用内存.我添加了另外10G的交换,并将缓存的内存提升到33G.如果我添加另一个10G的交换,我会将6G更多地识别为缓存.一直以来,只报告使用了几千字节的交换.就好像内核需要为它识别或报告为缓存的每个位都有匹配的交换.这是40G交换顶部的输出:
top - 23:06:45 up 46 days, 11:56, 2 users, load average: 0.01, 0.12, 0.13
Tasks: 586 total, 1 running, 585 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 65960100k total, 64356228k used, 1603872k free, 197800k buffers
Swap: 39062488k total, 3128k used, 39059360k free, 33101572k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6440 1002 20 0 26.3g 1.5g 11m S 0 2.4 2:02.87 java
6538 1003 20 0 9.8g 994m 4564 S 0 1.5 0:17.70 mysqld
4707 dbourget 20 0 27472 8728 1692 S 0 0.0 0:00.38 bash
Run Code Online (Sandbox Code Playgroud)
任何建议高度赞赏.
编辑2:这是来自/ proc/spl/kstat/zfs/arcstats的arc*值
arc_no_grow 4 0
arc_tempreserve 4 0
arc_loaned_bytes 4 0
arc_prune 4 0
arc_meta_used 4 1531800648
arc_meta_limit 4 8654946304
arc_meta_max 4 8661962768
Run Code Online (Sandbox Code Playgroud)
ZFS没有激活L2ARC
jll*_*gre 14
ZFS ARC缓存和存储在内核内存中的其他ZFS相关数据很可能使用此内存.ARC缓存有点类似于缓冲区缓存,所以通常没有什么可担心的,因为如果需要它,ZFS会释放这个内存.
但是,缓冲区缓存和ARC缓存之间存在细微差别.第一个可立即分配,而ARC缓存则不可分配.ZFS监视可用的可用RAM,当它太低时,它会向其他用户释放RAM.
这适用于大多数应用程序,但是当报告少量可用RAM时,它们中的一小部分要么混淆,要么为发布过程分配太多/太快的内存以正确地保持速度.
这就是为什么ZFS允许减小允许使用ARC大小的最大大小的原因.此设置在/etc/modprobe.d/zfs.conf文件中完成.
例如,如果您希望ARC永远不会超过32 GB,请添加以下行:
options zfs zfs_arc_max=34359738368
Run Code Online (Sandbox Code Playgroud)
要获取当前ARC大小和各种其他ARC统计信息,请运行以下命令:
cat /proc/spl/kstat/zfs/arcstats
Run Code Online (Sandbox Code Playgroud)
该size指标将显示ARC的当前大小.请注意,其他与ZFS相关的内存区域也可能占用RAM的份额,即使不再使用也不一定能快速释放.最后,Linux上的ZFS比Solaris本地执行肯定不太成熟,所以你可能会被这样的错误被击中一个.
另请注意,由于共享存储池设计,卸载ZFS文件系统不会释放任何资源.您需要导出池以便最终释放内存.