为什么在有大量可用内存的情况下使用 Swap?

为什么在有大量可用内存的情况下使用 Swap?

我拥有非常好的网络(专用)服务器,并且拥有良好的内存资源:

System information
Server load     2.19 (8 CPUs)   
Memory Used     29.53% (4,804,144 of 16,267,652)    
Swap Used   10.52% (220,612 of 2,097,136)   

如您所见,当有足够的可用内存时,我的服务器正在使用交换。

这是正常的吗?还是配置或编码有问题?

注意:
我的 MySQL 进程由于某种原因使用了超过 160% 的 CPU 能力;我不知道为什么,但我同时在线的用户不超过 70 个...

答案1

这是非常正常的。

在系统启动时,许多服务都会启动。这些服务会自行初始化、读取配置文件、创建数据结构等。它们会占用一些内存。许多服务在系统运行期间将永远不会再次运行,因为您不会使用它们。其中一些服务可能会在几小时、几天或几周内运行。然而,所有这些数据都在物理内存中。

当然,系统不能丢弃这些数据。它无法证明这些数据永远不会被访问。例如,这些服务之一可能是为您提供远程访问盒子的服务。您可能一周都没有用过它,但如果您确实使用它,它最好能正常工作。

但是系统知道它可能希望将物理内存用于磁盘缓存等用途,或者用于其他可以提高性能的方式。因此,它会进行机会性交换。当没有更好的事情可做时,它会使用交换空间将很长时间未使用的数据写入磁盘。但是,它仍将页面保留在物理内存中。因此,无需交换即可访问它们。

现在,如果系统稍后需要该物理内存用于其他用途,它可以简单地丢弃这些页面,因为它已经将它们写入交换区。这为系统提供了两全其美的方案。数据仍然保存在内存中,因此无需从磁盘读取即可访问。但如果系统需要该内存用于其他用途,则无需先将其写出。这是一个巨大的胜利。

答案2

如果过去某个时候您需要的内存比机器中的物理 RAM 多,则可能会发生这种情况。那时一些数据将被写入交换空间。

当稍后释放内存时,交换区中的数据不会自动读回 RAM:只有当某个进程确实需要交换区中的数据时才会发生这种情况。这是完全正常的。

至于您的 mysql 进程:这完全取决于您运行的查询类型。理论上,无论您的用户数量有多少,2 个非常复杂的查询可能就足以获得这样的负载。您可以启用慢速查询日志以更深入地了解哪些查询是负载密集型的。

答案3

您还可以通过 更改此行为sysctl -w vm.swappiness=10,这将大大减少交换的使用,直到真正需要它为止。

至于 MySQL,您是否至少使用调优入门指南脚本?

答案4

正如 David 所解释的,这可能是 Linux 内核的正常行为,但也可能是MySQL“交换疯狂”问题. 在您的例子中(8 个 CPU、总共 16 GB RAM、已使用 5 GB),要实现此目的,您的计算机应为 NUMA 系统,具有 4 个节点(插槽)、每个节点 4 GB RAM 以及 4 GB 的 MySQL InnoDB 缓冲池。

简而言之(您应该阅读上面的链接以了解完整的详细信息),事情如下:

  1. 当系统启动时,进程会分布在所有 NUMA 节点上,使用其部分内存。
  2. 当 MySQL 启动时,它会为 InnoDB 缓冲池分配 4 GB,填充 NUMA 节点的 RAM 并使用其他节点上的一些 RAM。
  3. 然后,Linux 内核无法将分配的 RAM 从一个 NUMA 节点移动到另一个 NUMA 节点,因此认为从饥饿节点换出页面是个好主意(或者需要换出页面,因为需要换入页面)。

为了避免这种情况,请更改 MySQL 的内存分配以在所有核心上分配 RAM(有关更多详细信息,请参阅上面的链接)。

相关内容