13

我的 Ubuntu 12 服务器神秘地丢失/浪费内存。它有 64GB 的内存。即使我关闭了所有应用程序,也显示大约 46GB 已使用。此内存未报告为用于缓冲区或缓存。

top 的结果(当我的应用程序正在运行时;应用程序使用大约 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)

请注意,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

什么在使用我的记忆?我已经尝试了所有可能遇到的诊断。论坛上挤满了问同样问题的人,因为 Linux 正在使用他们的内存作为缓冲区/缓存。这似乎不是这里发生的事情。

该系统可能是 lxc 容器的主机。上面报告的 top 和 free 结果来自主机,但在容器中报告了类似的内存使用情况。停止所有容器不会释放内存。一些 46G 仍在使用中。但是,如果我重新启动主机,内存是空闲的。过段时间就达不到46G了。(我不知道需要几天还是几周。需要几个小时以上。)

系统使用 zfs 也可能是相关的。Zfs 被称为内存饥渴,但不是那么多。该系统在两个 raidz 池上具有两个 zfs 文件系统,一个是 1.5T,一个是 200G。我有另一台服务器出现完全相同的问题(46G 没有使用),并且配置几乎相同,但使用 3T 阵列而不是 1.5T。每个 zfs 文件系统都有很多快照(大约 100 个)。我通常在任何时候都挂载每个文件系统的一个快照。卸载那些并没有让我恢复记忆。

我可以看到上面屏幕截图中的 VIRT 数字与使用的内存大致一致,但即使在我关闭这些应用程序之后,内存仍然在使用——即使在我关闭运行它们的容器之后也是如此。

编辑:我尝试添加一些交换,并且发生了一些有趣的事情。我加了30G的swap。片刻之后,标记为缓存在顶部的内存量从 5G 增加到了 25G。free -m 表示大约多出 20G 可用内存。我添加了另外 10G 的交换空间,并将缓存内存提高到 33G。如果我再添加 10G 的交换,我会得到 6G 更多的被识别为缓存。一直以来,报告只使用了几千字节的交换。就好像内核需要为它识别或报告为缓存的每一位匹配交换。这是带有 40G 交换的 top 的输出:

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      

任何建议高度赞赏。

编辑 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

没有为 ZFS 激活 L2ARC

4

1 回答 1

15

该内存很可能被 ZFS ARC 缓存和其他存储在内核内存中的 ZFS 相关数据使用。ARC 缓存有点类似于缓冲区缓存,因此通常无需担心它,因为如果需要,ZFS 会释放此内存。

但是,缓冲区高速缓存内存和 ARC 高速缓存内存之间存在细微差别。第一个可以立即分配,而 ARC 缓存则不能。ZFS 监视可用的空闲 RAM,当可用 RAM 太低时,它会将 RAM 释放给其他使用者。

这适用于大多数应用程序,但其中少数应用程序要么在报告可用 RAM 量少时感到困惑,要么为发布过程分配太多/太快的内存以正确跟上节奏。

这就是 ZFS 允许减小 ARC 允许使用的最大大小的原因。此设置在/etc/modprobe.d/zfs.conf文件中完成。

例如,如果您希望 ARC 永远不会超过 32 GB,请添加以下行:

options zfs zfs_arc_max=34359738368

要获取当前 ARC 大小和各种其他 ARC 统计信息,请运行以下命令:

cat /proc/spl/kstat/zfs/arcstats

size指标将显示 ARC 的当前大小。请注意,其他与 ZFS 相关的内存区域也可能会占用 RAM,即使不再使用也不一定会很快释放。最后,Linux 上的 ZFS 肯定不如 Solaris 本机实现成熟,因此您可能会遇到这样的错误

还要注意,由于共享存储池设计,卸载 ZFS 文件系统不会释放任何资源。您需要导出一个内存池才能最终释放内存。

于 2013-09-15T02:19:04.723 回答