如果一个 CentOS 安装在具有 16GB RAM 的双四核 XEON 计算机上,并且要运行一个带有 mysql 后端的 php 网站(中等/重负载),您会给它分配多少 SWAP?
答案1
不会超过一两千兆——你想要一点交换可用,以防万一,因为它可以帮助事情更好地工作,但如果你到了大量交换的地步,机器就会变得毫无用处——在真正的灾难性情况下,你实际上最好使用较小的交换空间,因为这样你会尽早触发 OOM 杀手。
答案2
很抱歉回答得太长了。我一直想把这些东西放在容易拿到的地方!
TLDR;从理论上讲,答案是“可能不低于所有应用程序想要使用的常驻内存总量”
如果你和我在一起,我会尽力解释。
关于虚拟内存
我觉得现在大家对交换空间的价值和用途存在一个普遍的误解。人们通常认为交换空间是内存不足时的“储备库”。是的,这在一定程度上是正确的,但内核不想使用你的掉期作为储备银行。 此外内核永远不会调用磁盘来获取您想要的数据!
在应用程序空间中,内核会在内存中保存许多内容。
- 映射文件数据。
- tmpfs 文件系统。
- 运行时分配的原始应用程序内存。
- 应用程序代码(例如 ELF 格式的数据段中的内容)
- 私下映射文件数据。
为了内存管理的目的,内存分配是支持以某种形式通过支撑设备。
文件备份内存是来自文件的内存,在典型的操作系统中,内存占系统内存分配的绝大部分。它包括已加载的共享库、从磁盘读取并存储在页面缓存中的文件以及从磁盘映射的文件(事实上,内核不会区分页面缓存中的文件和映射的文件,因为它们本质上是同一件事)。
从内核的角度来看,这种内存的优点在于它是可丢弃的,也就是说,如果您需要内存来做其他事情,那么应该可以转储这些页面,而当突然需要内存时,这正是页面缓存所做的。
匿名支持内存是另一回事。这个区域的内存是匿名的,因为磁盘上没有文件实际包含这些数据。这通常由应用程序堆栈、堆、tmpfs 中的任何内容以及 mmapped 数据组成,这些数据是私有的并且已被修改(因为它无法将这些内容同步回磁盘)。由于文件系统上没有有效的文件可以在这些页面发生更改时将其写回,因此匿名支持的内存由交换介质支持。
现在,内核知道,当内存稀缺时,放弃文件支持的内存而使用匿名映射内存要便宜得多,这是因为匿名数据比文件支持的数据更有可能被“弄脏”,事实上,默认情况下,内核认为匿名支持的内存比文件支持的内存有价值 80 倍,这实际上是 swappiness 修饰符在 linux 上的作用(参见这篇文章这里如果你想知道 swappiness 参数到底改变了什么)。
最坏的情况
服务器失控和 OOM 的最坏情况是,它处理 I/O 请求的时间比处理内存分配请求的时间要多得多。有两种情况可以触发此标准。
- 一直交换匿名内存以获取所需页面,或为应用程序分配更多页面。
- 由于数据不在内存中,因此从磁盘获取数据所花的时间比执行需要 CPU 时间的进程所花的时间要多。
第一个是人们普遍认为的问题。也就是说,由于大量内存位于交换区内,因此需要将匿名内存从 RAM 中交换出来,将其放回交换区,然后从交换区中取出一些内存并将其放入实际 RAM 中。此操作非常昂贵,会使机器速度变慢,甚至可能陷入无法恢复的境地(因为排队等待页面请求的内容比 I/O 可以提供的内容更多)。
第二个问题考虑得较少,但同样重要。如果你将几乎所有内存都分配给实际应用程序数据,那么你不会坚持太久。几乎每个应用程序都依赖于从文件系统读取文件来运行,这可能是因为某些指令存在于共享库中,或者因为你需要读取 /etc/resolv.conf 以进行库调用,或出于任何其他目的。完全可以停止操作系统 - 但仍有足够的内存来容纳所有应用程序,但由于排队了如此多的 I/O 请求,因此没有任何请求有机会正确完成。
内核想用你的交换空间做什么
内核想要使用你的交换来摆脱浪费内存的页面,以便它可以将该内存用于其他用途。
基本上,在正常运行中,内核喜欢积极地用从磁盘读取的数据填充页面缓存,这意味着它不会读取磁盘中的相同数据。这是很好的设计,可以大大减少 I/O。现在,可能有一些应用程序在内存中休眠 3 天,醒来后执行大量工作,然后再休眠 3 天。
内核希望用这些数据交换出去,为文件系统活动腾出空间,因为您实际使用这些页面的可能性比用于应用程序的页面高得多。从这个意义上讲,交换可能是对交换介质的 16kb 事务,您几乎感觉不到,但作为回报,您释放了 16kb 内存,可以用于存储四个文件的数据。
内核不想使用 swap 做什么
内核肯定不想使用你的交换来通过换出一些其他匿名内存来分配更多的匿名内存,这是人们最担心的情况,而且这是正确的。
然而,我应该指出,如果你分配了太多的内存,以至于内核别无选择,只能这样做,那么这是一个系统管理员的配置问题,而不是内核本身的问题——它只是试图根据你给它的选项做到最好!
如果您拥有大量的交换空间,您是否会增加使用它的机会?
不!如果您有 1G 内存和 4G 交换空间,那么您的数据被交换的可能性不到 80%!只有当内存中的页面可以更好地用于执行其他操作时,内核才会使用交换空间!
完全不使用交换是否有利
我永远不会这样做。交换允许操作系统释放你需要但从未使用的内存。如果你没有交换,你只是吞噬了你永远无法恢复的内存,而通过允许页面缓存来获得显着的性能改进,你可能会看到显着的性能改进。
最好的交换是什么
从理论上讲,找出需要从堆中分配内存的安全性(如可重入库调用)所需的常驻内存量 +20%,然后将交换设置为该量。这将(理论上)允许操作系统在需要为更有用的东西腾出空间时交换所有匿名内存。
如果我得到内核机会来换掉所有危险的东西,对吧?
请记住,内核并不想通过交换为更多的匿名内存分配让路,它只会换出未使用的页面,以便更好地利用空间。
如果您交换匿名内存只是为了从更多的匿名内存中分配,那么您做错了什么并且需要更多的 RAM 或重新调整您的应用程序堆栈。
你需要多少 RAM
当然,您需要允许足够的 RAM 来运行所有应用程序,但您可能应该允许额外的 2G RAM 来填充页面缓存——甚至更多。页面缓存使您的计算机运行速度更快,磁盘使用寿命更长。如果您考虑运行网络服务器,为页面缓存提供更多内存是一个好主意,因为您可以从页面缓存中检索和重用大量静态内容(如果您的网络服务器吞吐量为 5mb/s,您真的不想检索从磁盘生成的 5mb/s 内容!)。
如果你真的不相信 Linux 可以正确交换,该怎么办
如果你真的担心,你可以分配比你拥有的更多的内存:
- 设置交换空间不超过你的 RAM
- 将 /proc/sys/vm/overcommit_memory 设置为 2
- 将 /proc/sys/vm/overcommit_ratio 设置为一个实际上永远不会超过物理 RAM 限制的值。请参阅内核文档计算出这个数字对你来说是多少。
为我的应用程序调整内存的最佳方法是什么
- 了解 swappiness 的实际作用。
- 使用 CGroups 为每个应用程序分配正确的资源。
- 改变上面提到的过度提交模式,使操作系统强制执行严格的限制。
- 使用上述 cgroups 设置应用程序的 OOM 优先级真的如果你的内存不足并且应用程序真的如果你的记忆力不够就想抛弃它。
供应商建议采用不同的配置。
听听这些。有些应用程序的编写方式是故意调用内核,让其页面比其他页面更活跃。老实说,这是一个卑鄙的伎俩,但它会破坏内核无缝管理内存的能力。如果您的供应商向您提供了具体信息,那么他们很可能属于这一类,请听取他们的意见。
总之
- 交换空间是用来放置浪费的内存的,而不是“备用内存”
- 拥有大量的交换空间不会对您使用它的机会产生任何影响。
- 内核确实想阻止您访问磁盘以获取数据。这适用于页面缓存,就像它适用于交换空间一样 - 甚至更平等。
- 内核会尽力遵守您为运行的应用程序提供的设置。但是,如果您有 500 个 Apache 子进程,全部占用 32M 内存,则不要惊讶于 OOM。这是您选择的配置的问题,而不是内存管理的问题。
内核通常能够很好地管理虚拟内存。几乎总是会出现这样的情况:您的应用程序分配的内存比您希望使用的内存要多,这就是导致 OOM 的原因。
交换曾经被用作“备用内存”,但现在它不再是主要用途了,所以不要想着那样使用它。相反,要意识到你的内核可能最清楚它想用你的内存做什么。给它空间来做这些决定,你将从整体性能的提升中受益。
答案3
摘自文档“Red Hat® Enterprise Linux® 5 上的 Oracle 10g Server 部署建议”。
Oracle 在 MetaLink Note 169706.1 中提供了有关交换大小的通用建议。这些建议可能会导致在具有大量内存的系统上创建非常大的交换空间。非常大的交换可能会导致严重的系统性能下降,可以通过减少交换空间来解决。Red Hat 不建议在 Red Hat Enterprise Linux 5 上为交换分配超过 4GB 的空间。
因此对于 16GB 来说,交换空间不应超过 4GB。
附言:还值得注意的是,调用oom
几乎总是比使用整个 I/O 带宽的无法使用的换出进程更好。
答案4
我记得 Linux 文档中是这样写的:如果你的 RAM 大于 2GB,那么 swap = (ramSize + 2)。如果小于 2GB,那么 swap = (ramSize*2)