我有很好的网络(专用)服务器,具有良好的内存资源:
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 个并发用户......
这是完全正常的。
在系统启动时,许多服务启动。这些服务进行自我初始化、读入配置文件、创建数据结构等。他们使用一些内存。由于您没有使用它们,因此在系统启动的整个过程中,其中许多服务将永远不会再次运行。其中一些可能会在数小时、数天或数周内运行。然而,所有这些数据都在物理内存中。
当然,系统不能把这些数据丢掉。它不能证明它永远不会被访问。例如,其中一项服务可能是为您提供远程访问盒子的服务。您可能一周内没有使用它,但如果您使用它,它会更好用。
但是系统知道它可能希望将该物理内存用于诸如磁盘缓存之类的东西或以其他可以提高性能的方式。所以它会进行机会性交换。当它无事可做时,它会使用交换空间将很长时间未使用的数据写入磁盘。但是,它仍然将页面保留在物理内存中。所以他们仍然可以访问而无需交换它们。
现在,如果系统稍后需要该物理内存用于其他用途,它可以简单地丢弃这些页面,因为它已经将它们写入交换。这为系统提供了两全其美的优势。数据仍然保存在内存中,因此无需从磁盘读取即可访问。但是,如果系统出于其他目的需要该内存,则不必先将其写出。大获全胜。
如果在过去的某个时候您需要的内存比机器中的物理 RAM 多,就会发生这种情况。那时一些数据将被写入交换空间。
当稍后内存被释放时,swap 中的数据不会自动读回 RAM:只有当某些进程实际需要 swap 中的数据时才会发生这种情况。这是完全正常的。
至于你的 mysql 进程:这完全取决于你运行的查询类型。理论上 2 非常复杂的查询可能足以获得这样的负载,无论您的用户数量如何。您可以启用慢速查询日志以更深入地了解哪些查询是负载密集型的。
您也可以通过 更改此行为
sysctl -w vm.swappiness=10
,这将大大减少 swap 的使用,直到真正需要它为止。至于 MySQL,您是否至少使用tuning-primer.sh脚本执行了基线配置测试?
正如 David 解释的那样,这可能是 Linux 内核的正常行为,但也可能是MySQL“swap insanity”问题的发生。在您的情况下(8 个 CPU,总共 16 GB RAM,已使用 5 GB),要做到这一点,您的计算机应该是一个 NUMA 系统,具有 4 个节点(套接字)和每个节点 4 GB 的 RAM 以及 4 个 MySQL InnoDB 缓冲池国标。
简而言之(您应该阅读上面的链接以获取完整的详细信息),这就是发生的事情:
为避免这种情况,请更改 MySQL 的内存分配以在所有内核上分配 RAM(有关更多详细信息,请参见上面的链接)。