答案1
这不是一个问题,很可能是正常的。许多代码(可能还有数据)很少使用,因此系统会将其交换出去以释放内存。
只有在内存不断被换入换出时,交换才会成为问题。这种活动会降低性能,并表明系统其他地方存在问题。
如果你想监控你的交换活动,你可以使用几个实用程序,但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
忽略第一行,因为这是系统启动以来的活动。请注意下面的si
和so
列---swap--
;它们通常应该是相当小的数字,如果不是大多数时候为 0 的话。
另外值得一提的是,这种抢占式交换可以通过内核设置来控制。文件/proc/sys/vm/swappiness
包含一个介于 0 到 100 之间的数字,用于告诉内核以何种程度积极地换出内存。cat 该文件以查看其设置。默认情况下,大多数 Linux 发行版将其默认为 60,但如果您不想在内存耗尽之前看到任何交换,请将 0 回显到文件中,如下所示:
echo 0 >/proc/sys/vm/swappiness
可以通过添加来永久实现
vm.swappiness = 0
到/etc/sysctl.conf
。
答案2
如果没有更好的事情可做,Linux 会先将页面写入磁盘。不是意味着它将从内存中逐出这些页面。只是万一必须在将来的某个时候逐出这些页面,它不需要等待它们被写入磁盘,因为它们已经在那里了。
毕竟,内存耗尽的原因可能是因为您的机器已经在努力工作,您不想再通过交换来增加负担。最好在机器无所事事时进行交换。
出于类似的原因,您的内存应该始终保持满载状态。内存页面、文件系统缓存,tmpfs
内存中可以容纳的东西太多了。实际上,您应该担心您的内存是否为空;毕竟,您为它付出了很多钱(至少与相同数量的磁盘空间相比),所以最好使用它!
答案3
使用的交换并不坏,但大量的交换活动
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
专栏swapd完全没有问题。列上的非零值锡和所以对服务器性能来说是致命的。特别是那些有大量 RAM 的服务器。
最好在具有几 GB RAM 的机器上禁用 swapinness:
sysctl -w vm.swappiness=0
这不会禁用交换。它只会指示 Linux 使用交换作为最后的手段。这会浪费几 MB 不需要在 RAM 中的程序……但最好交换膨胀您的磁盘访问队列。
编辑 1:为什么 swappiness 的默认值不是最佳的
我们还记得二十年前,一台大型 486 只有 32Mb RAM。当整个 RAM 可以在很短的时间内移动到磁盘时,交换算法就被开发出来了。即使是当时速度较慢的磁盘。这就是为什么默认交换策略如此激进的原因。当时 RAM 是瓶颈。从那时起,RAM 大小增加了 10,000 多倍,而磁盘速度却不到 10 倍。这将瓶颈转移到磁盘带宽上。
编辑 2:为什么这样的活动对服务器来说是致命的?
硅和所以在具有大量 RAM 的机器上,活动是致命的,因为这意味着系统正在与自身争夺 RAM。结果就是磁盘,即使是大型存储,与 RAM 相比也太慢了。激进的交换有利于内核磁盘缓存而不是应用程序数据,并且是争夺 RAM 的最常见原因。由于操作系统必须在每个锡,交换提供的额外缓存的生存时间太短,无论如何都无法使用。结果是,您正在占用磁盘带宽来存储可能不会使用的缓存,并暂停您的程序以等待锡页面。这意味着这会消耗大量关键资源,而对应用程序却几乎没有任何好处。
请注意响应的标题“在具有大量 RAM 的服务器上有大量交换活动”。这不适用于偶尔有 si 和 so 活动的机器。如果在操作系统中开发出更智能的交换算法,那么将来这可能不再适用。
修改 3:“冷门”页面
人们把交换算法浪漫化了。有人说“它占用较少使用的 RAM 页面”,但这根本不是内核所做的。关于交换,很难理解的一点是内核不知道什么是“冷页面”。内核没有一个很好的指标来确定页面是否被使用或可能在不久的将来被使用。为了避免这种情况,内核或多或少随机地将页面放入交换中,不需要的页面则留在那里。该算法的问题是,页面需要进入交换才能知道应用程序是否需要它们。这意味着很多“热”页面将进入交换。这样做的问题是磁盘与 RAM 相比太慢了。其结果是,当交换开始时,所有应用程序都会随机暂停等待磁盘,这会阻碍延迟和吞吐量。
我建立了自己的基准测试,这是许多具有相当大容量的应用程序非常常见的现实场景。从我的测试来看,使用交换时,我没有看到吞吐量或延迟方面的好处。远非如此。当交换开始时,吞吐量和延迟至少会降低一个数量级。
我对此做了进一步的阐述:我理解交换不是用于处理的。交换仅用于紧急情况。当太多应用程序同时运行并且内存激增时。如果没有交换,这会导致内存不足错误。我认为交换的使用是开发和生产团队的失败。这只是一种观点,远远超出了我们在这里讨论的范围,但这是我的想法。当然,我的应用程序本身具有出色的内存管理。
答案4
我注意到,当代理大量交换时,MySQL Cluster 复制会变慢或失败。也许某些应用程序不介意,甚至可能从交换中受益,但数据库似乎确实受此影响。然而,我在论坛上看到的许多讨论都是脱离具体工作负载讨论的交换。
在 DBA 世界中,共识似乎是“当您运行 MySQL(或任何其他 DBMS)时,您不希望在交换空间中看到任何 I/O,这是常识。扩展缓存大小(在 MySQL 的情况下使用 innodb_buffer_pool_size)是标准做法,以确保有足够的可用内存,因此不需要交换。
但是,如果你犯了一些错误或计算错误,并且发生了交换,该怎么办?它对性能的影响到底有多大?这正是我要调查的。“
我希望读者会发现以下链接是合适的。
https://www.percona.com/blog/2017/01/13/impact-of-swapping-on-mysql-performance/
https://www.percona.com/blog/2010/01/18/why-swapping-is-bad-for-mysql-performance/