我是否应该担心在具有近 40GB 可用内存的主机上使用交换?

MrD*_*Duk 40 performance memory centos swap

我有一个生产主机,如下:

顶

系统使用了 1GB 的交换空间,同时保持了近 40GB 的空闲、未使用的内存空间。我应该担心这个吗,或者这主要是正常的吗?

use*_*517 68

这不是问题,很可能是正常的。很少使用大量代码(可能还有数据),因此系统会将其换出以释放内存。

如果内存不断地换入和换出,交换通常只是一个问题。正是这种活动会降低性能并暗示系统其他地方存在问题。

如果您想监控您的交换活动,您可以使用多个实用程序,但vmstat通常非常有用,例如

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 348256  73540 274600    0    0     1     9    9    6  2  0 98  0  0
 0  0      0 348240  73544 274620    0    0     0    16   28   26  0  0 100  0  0
 0  0      0 348240  73544 274620    0    0     0     0   29   33  0  0 100  0  0
 0  0      0 348240  73544 274620    0    0     0     0   21   23  0  0 100  0  0
 0  0      0 348240  73544 274620    0    0     0     0   24   26  0  0 100  0  0
 0  0      0 348240  73544 274620    0    0     0     0   23   23  0  0 100  0  0
Run Code Online (Sandbox Code Playgroud)

忽略第一行,因为这是系统启动以来的活动。请注意;下的siso---swap--如果大部分时间不是 0,它们通常应该是相当小的数字。

另外值得一提的是,这种抢占式交换可以通过内核设置进行控制。文件 at/proc/sys/vm/swappiness包含一个 0 到 100 之间的数字,它告诉内核换出内存的积极程度。Cat 文件以查看它的设置。默认情况下,大多数 Linux 发行版默认为 60,但如果您不想在内存耗尽之前看到任何交换,请将 0 回显到文件中,如下所示:

echo 0 >/proc/sys/vm/swappiness
Run Code Online (Sandbox Code Playgroud)

这可以通过添加永久化

vm.swappiness = 0
Run Code Online (Sandbox Code Playgroud)

/etc/sysctl.conf

  • 另外值得一提的是,这种抢占式交换可以通过内核设置进行控制。/proc/sys/vm/swappiness 中的文件包含一个 0 到 100 之间的数字,它告诉内核换出内存的积极程度。Cat 文件以查看它的设置。默认情况下,大多数 Linux 发行版默认为 60,但如果您不想在内存耗尽之前看到任何交换,请将 0 回显到文件中,如下所示:`echo 0 >/proc/sys/vm/swappiness`。这可以通过将 `vm.swappiness = 0` 添加到 /etc/sysctl.conf 来永久化。 (14认同)
  • @JonasWielicki:即使使用 `swappiness=7` 或其他东西,长期未使用的页面也会被换掉。`swappiness=0` 和任何其他值之间存在很大差异,即使是低值。内核默认的 `swappiness=60` 通常适用于服务器,它仅适用于桌面交互使用,其中低交换是好的。但是将它设置为 7 或其他东西应该不会有太大伤害。(但我没有检查,我不是服务器系统管理员)。 (4认同)
  • @PeterCordes 在您施加内存压力之前,任何“swappiness”都很好用。在压力下,您会看到 `swappiness=7` 使文件缓存 *几乎完全* 长时间处于饥饿状态,而 `swappiness=60` 清理了大量缓存,但也会在几秒钟内开始交换。它仍然是缓存,但以一种更加平衡的方式进行。 (2认同)

Jör*_*tag 25

如果 Linux 无事可做,它会先发制人地将页面写入磁盘。但这并不意味着它就会收回从内存中这些网页,但。只是在将来某个时候它必须驱逐这些页面时,它不需要等待它们被写入磁盘,因为它们已经在那里了。

毕竟,您内存不足的原因可能是因为您的机器已经在努力工作,您不想通过交换给它带来额外的负担。最好在机器什么都不做时进行交换。

出于类似的原因,您的内存应该始终是满的。内存页面、文件系统缓存、tmpfs内存中可以保存的东西太多了。真的,你应该担心你的记忆是否是空的;毕竟,你为它付出了很多(至少与相同数量的磁盘空间相比),所以最好使用它!


小智 11

使用的掉期还不错,但大量的掉期活动是

  vmstat 1
  procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
  6  0 521040 114564   6688 377308    8   13   639   173    0 1100  5  4 90  0
  1  0 521040 114964   6688 377448    0    0   256     0    0 1826  3  4 94  0
  0  0 521040 115956   6688 377448    0    0     0     0    0 1182  7  3 90  0
  0  0 521036 115992   6688 377448    4    0    16     0    0 1154 10  2 88  0
  3  0 521036 114628   6696 377640    0    0   928   224    0 1503 15 17 67  1
Run Code Online (Sandbox Code Playgroud)

swapd完全没有问题。在列非零个值,并因此是致命的服务器性能。特别是那些有大量内存的。

最好在具有几 GB 内存的机器上禁用交换:

sysctl -w vm.swappiness=0
Run Code Online (Sandbox Code Playgroud)

这不会禁用交换。它只会指示 Linux 使用交换作为最后的手段。这将浪费几 MB 不需要在 RAM 中的程序......但最好是交换膨胀你的磁盘访问队列。

编辑 1:为什么 swappiness 的默认值不是最优的

我们必须记住二十年前,一个大的 486 只有 32Mb 的 RAM。当整个 RAM 可以在几分之一秒内移动到磁盘时,交换算法就被开发出来了。即使使用当时较慢的磁盘。这就是默认掉期政策如此激进的原因。RAM 是当时的瓶颈。从那时起,RAM 大小增加了 10,000 多倍,磁盘速度增加了不到 10 倍。这将瓶颈转移到磁盘带宽上。

编辑 2:为什么 si 如此活动对服务器来说是致命的?

因此与吨的RAM机活动是致命的,因为手段的系统与自身奋斗的RAM。与 RAM 相比,磁盘,即使是大存储空间也太慢了。主动交换有利于内核磁盘缓存而不是应用程序数据,并且是争夺 RAM 的最常见来源。由于操作系统必须在每个si上释放磁盘缓存,因此交换提供的额外缓存的生存时间太短而无用。结果是您占用了磁盘带宽来存储可能不会使用的缓存并暂停您的程序以等待si页。这意味着消耗大量关键资源而对应用程序几乎没有好处或没有好处。

请注意响应的标题“具有大量 RAM 的服务器上的大量交换活动”。这不适用于偶尔有 si 等活动的机器。如果操作系统中开发了更智能的交换算法,这在未来可能不适用。

编辑 3:“冷”页面

人们将交换算法浪漫化。有人说“它占用了较少使用的 RAM 页”,但这根本不是内核所做的。关于交换,很难理解的是内核不知道什么是“冷页”。内核没有一个很好的指标来确定页面是否被使用或可能在不久的将来被使用。为了避免内核或多或少随机地将页面放入交换中,并且不需要的页面留在那里。该算法的问题在于,页面需要进行交换才能知道应用程序是否需要它们。这意味着很多“热门”页面将被交换。问题是磁盘与 RAM 相比太慢了。

我构建了自己的基准测试,这是一个现实场景,对于许多具有体面量的应用程序来说非常常见。从我的测试中,我发现使用交换时吞吐量或延迟没有任何好处。离得很远。当交换开始时,它会使吞吐量和延迟至少降低一个数量级。

我更进一步:我知道交换不是用于处理的。掉期仅用于紧急情况。那些同时运行太多应用程序并且您会遇到内存峰值的时刻。如果没有交换,这将导致内存不足错误。我认为交换使用是开发和生产团队的失败。这只是一种超出我们在这里讨论的范围的意见,但就是我的想法。当然,我的应用程序本身具有出色的内存管理。

  • “最好禁用交换机制” 最好,为什么?(最好,用于什么目的?)默认值可能并不适合所有用途,但我仍然需要一个理由来改变它。 (9认同)
  • `si` 对你的服务器来说比 `bi` 更致命吗?两者都意味着某个程序正在等待 4096 字节从磁盘读取到内存。`bi` 来自任何文件,而 `si` 来自特定的狭窄类别的文件(但它们的字节通过完全相同的路径移动*同样快*)。 (3认同)
  • 带有 128MB 内存的 486 非常罕见,会被认为是大型机或超级计算机 - 因此 CPU 不太可能是 486。我的旧 486 有 4MB 内存,我很羡慕我朋友的机器有 16MB 内存(大型服务器有 16 到 32 MB 的 RAM)。快进到奔腾,我们开始看到 8 到 16 MB 是正常的。Pentium3 首次出现时(当 CPU 开始正常超过 1GHz 时)32MB 是正常的,而 Web 服务器通常有 64 到 128MB。 (2认同)

Aar*_*ron 8

这不是您问题的答案;而是帮助您做出明智决定的额外信息。

如果您想知道哪些进程具体使用了多少交换,这里有一个小 shell 脚本:

#!/bin/bash

set -o posix
set -u

OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"` ; do
  PID=`echo $DIR | cut -d / -f 3`
  PROGNAME=`ps -p $PID -o comm --no-headers`

  SUM=0
  for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'` ; do
    let SUM=$SUM+$SWAP
  done
  echo "PID=$PID - Swap used: $SUM - ($PROGNAME )"

  let OVERALL=$OVERALL+$SUM
done
echo "Overall swap used: $OVERALL"
Run Code Online (Sandbox Code Playgroud)

我还应该补充一点,tmpfs 也会换掉。这在使用 systemd 的现代 linux 系统上更为常见,这些系统使用 tmpfs 创建用户空间 /tmp 覆盖。