昨天下午,我们将其中一个 Linode 实例(CentOS 5.7,64 位)的大小从 4GB 调整为 12GB。重启后,我立即注意到缓冲区的内存使用量疯狂地高 - 比我接触过的任何机器都高。即使在我使用最频繁的服务器上,我也很少看到缓冲区使用量超过 200MB。在此服务器上,当前缓冲区使用量为两个数量级比我们调整大小并重新启动之前更高。
这是迁移前后的数据的 munin 内存图:
munin 显示的数据与“free”的输出相吻合:
[erik@host ~]$ free -m
total used free shared buffers cached
Mem: 11967 10146 1820 0 7374 1132
-/+ buffers/cache: 1639 10327
Swap: 255 0 255
现在,我很清楚内核将未使用的内存用于缓存,但我对缓冲区的理解是缓冲区是不同的。它们用于临时存储写入,直到它们被提交到磁盘。这是正确的理解吗?此服务器的磁盘 IO 很少(它是一个 apache/php 网络服务器,DB 在其他地方,因此只有实质性的 IO 是 access_logs),因此,我预计缓冲区使用率会很低。
以下是同一时间段的网络流量图:
可以看到,调整大小前后流量没有实质性的变化。
在重启过程中,据我所知有三件事发生了变化:
- 我们获得了 Linode 本周早些时候提供的 4 个额外核心,总核心数达到 8 个。
- 我们使用的是“最新 64 位”内核,现在是 3.7.10-x86_64-linode30。我记得之前我们使用的是 3.0.18。
- 我们的 RAM 从 4GB 增加到了 12GB。
在这些变化中,我的直觉是新内核导致了缓冲区使用量的增加。不幸的是,目前,我们不能再承受停机时间的打击来降级到较早的内核,尽管如果我无法解决这个缓冲区使用问题,这可能最终是必要的。
我有几个问题:
- 你们中有人运行 3.7.10 内核吗?如果是,你们看到过类似的变化吗?
- 有哪些工具可以检查内核缓冲区及其大小?
- 我假设,像缓存一样,当其他应用程序需要时,内核将释放这块内存。这是正确的吗?
答案1
为了澄清这一点:
[缓冲区] 用于临时存储写入内容,直到它们被提交到磁盘。这是正确的理解吗?
不,那是不对的。
您似乎理解了缓存的概念。当从磁盘读取文件时,该文件将作为缓存保存在内存中。如果应用程序需要再次访问此文件,则访问来自 RAM,速度很快,而不是从磁盘再次访问文件,速度很慢。
如果应用程序需要写入此文件,则写入操作将在 RAM 中的文件上执行,速度很快,并且内核会将这些内存页面标记为“脏”。就应用程序而言,写入已完成,应用程序可以继续执行其操作。
内核稍后会处理将脏页刷新到磁盘的操作。您可以使用该sync
命令强制刷新所有脏页,否则您会看到刷新守护进程(pdflush 或 bdflush)不时被唤醒。
您可以随时使用 查看脏内存的数量cat /proc/meminfo | grep Dirty
。
为了纠正您的理解,Linux 将干净的页面缓存(已读取的文件)和脏的页面缓存(等待写入磁盘的文件)都算作“缓存”。
如果进程请求更多虚拟内存分配,则可以释放文件缓存。共享内存段和 tmpfs 也被报告为“缓存”,但这些不能像文件缓存那样被释放。
通常“缓冲区”是运行进程的内存分配。查看top -a
或类似内容,看看哪个进程占用了大部分 RAM。