在LAMP服务器上,我们需要交换分区吗?

我们在ubuntu-server上使用LAMP是否需要交换分区? 我认为不需要,但最好确保它不会导致一些意外的行为。
实际上,我的想法是:

  • 服务器从不休眠
  • 如果正在交换,则需要考虑负载平衡/流量整形等问题...

我对吗?我可以在生产服务器上关闭交换吗?

谢谢!

5个回答

我可以关掉生产服务器的交换空间吗?
不行。总是需要一些交换空间。
我曾经尝试过在生产服务器上关闭交换空间,大约一周后,在 WordPress 更新之后,PHP开始占用比我们预期更多的内存。当内存耗尽并且启用了交换空间时,系统会变慢(有时非常慢,有时稍微慢一点),但你仍然能够登录,找出问题并尝试修复。
当内存耗尽且没有交换空间时,进程会终止,系统会停滞,而你唯一的选择往往是重新启动。但在进行重新启动之前,很可能会发生故障。
在我的世界里,故障比缓慢要糟糕得多。
当然,如果你发现系统经常使用大量的交换空间(通常会使用一些来清除旧的缓存内容),显然存在问题(请增加内存)。但将其作为安全保护是明智的建议。
作为对SpamapS的评论的回应:
在“成功的网站”世界里,你拥有热备份、负载均衡和其他工具,这些工具可以让一台机器崩溃而对其余的网站没有任何影响。但这需要大量的资金。对于大多数网站来说,拥有冗余硬件并不经济实惠,即使它们赚钱。
我完全不同意你关于稳定运行时间的评论。在传统的电子商务设置中,如果人们看不到你的网站,他们就不能从你那里购买。这不仅仅是电子商务,所有在线商业利益都会遭受更多抨击,如果你的网站出现任何停机时间。我知道,因为我为公司托管网站和服务,并且管理自己的网站。慢速=不满意,但停机=愤怒。即使你每次只停机一分钟,如果用户看到“正在维护”的通知超过几次,他们会认为你无法保持网站的正常运行。
一个慢速的服务器并不理想,但交换空间并不是用来一直运行的,它是最后的手段,允许你在修复问题时继续运行事物。
你还假设这台机器只运行一个服务。如果你有大把资金可以将一切都拆分开来,这可能是真的;但在现实世界中,事情往往会被综合在一起。多个网站、ssh守护进程、ftp服务器、邮件服务器等等。一个进程泄漏到交换空间可能并不会影响其他服务。没有交换空间,每个服务都有同样的机会立即、随机地终止。你对此毫无控制。
当然,交换空间并不是唯一的解决方案。你需要监控来提醒你内存用尽,但对于大多数人来说,拔掉电源重启并不是解决之道。我相信这种方法适用于你负责的跨国网站,但对于我们这些凡夫俗子(构成了互联网的大多数),这样做就是商业自杀。

我也有类似的经历,有点像...这是我的失误而不是故意的决定。一个没有交换空间的服务器修复起来真是一场噩梦,特别是当它决定杀死sshd时。 - Javier Rivera
我有大约16GB的RAM,其中一半用于快速IO缓存,剩下的用于LAMP。交换空间始终是空闲的,有时可能会有几兆字节,但我认为它通常是关闭的... - Arman
就像其他人所说的,你可能拥有数百GB的RAM,但一个进程仍然可能泄漏到其中。在你的情况下,我不确定是否建议你选择RAM*1.5,但最好保留几个GB的交换空间,以备不时之需。 - Oli
3在成功的网站世界中,不响应比坏掉还糟糕。用户实际上会欣赏一个快速的失败(顺便说一下,你的JavaScript前端代码应该优雅地处理这个),但他们会因为慢而讨厌你。放弃交换,它只会延迟不可避免的结果。-1 - SpamapS
@SpamapS:如果我能留下一条评论,我会把所有星期一下午的愤怒都发泄给你,所以我编辑了这篇文章。简而言之:我尊敬地不同意。 - Oli
1@Oli:现在运行N+1不再需要大笔资金,甚至不需要太多的钱。事实上,它几乎不需要特殊技能。服务器由于各种原因可能会出现故障,但要防止这成为一个非问题并不难。如果你有一个独立的LAMP服务器完成所有任务,那么哪个花费更高?是建立两个以上的服务器和一个负载均衡器(在EC2上使用t1.micros和EBS快照,这样可以非常便宜),还是你的网站在最繁忙的一天无法使用?查看谷歌的数据...我认为很明显 http://bit.ly/hB1AD1 - SpamapS
另外,如果对你的需求更合适的话,你不需要一个交换分区,使用一个交换文件也可以很好地工作。 - NightwishFan
@SpamapS 这仍然至少是你的第一台服务器的同样多的钱。如果你想要积极地平衡和复制,甚至更多。小型运营无法(或不愿意)负担得起,而那些可能在16GB内存服务器上运行的难以横向扩展的大型应用程序非常昂贵。正如我已经解释过两次的那样,一点点的交换空间并不是为了长时间运行,而是为了修复问题后保持在线并继续经营。链接到谷歌关于速度的数据是无关紧要的,因为他们没有计算服务中断的成本(也就是说,他们不支持你所说的)。 - Oli
1非常好的回答,涵盖了真实世界的服务器案例。添加冗余硬件、负载均衡、监控、RAM缓存等都非常重要,如果你不因为节省交换空间而瞎折腾,你将有时间来设置和调试它们。 - ImaginaryRobots
@Oli:即使对于一个非常小的企业,他们也会明白当用户因为网站在你修复时慢了一个小时而离开,并且发誓永远不回来,他们就损失了金钱。具体多少呢?很难说,但过去我发现说服企业主接受相对较低的固定成本比变量未知因素(比如“我们何时会意外消耗服务器上的所有RAM”)更容易。然而,我认为这只马已经死了,所以我会放下我的重锤。 - SpamapS
@SpamapS:如果你想要快速失败,那很好:在你的Web服务器或应用程序中配置一个较低的超时时间。关闭交换空间是一种极其糟糕的方法,如果你遇到问题,这将使恢复甚至调试变得更加困难。顺便说一下,我相当确定EC2镜像是开启了交换空间的。 - poolie

我必须不同意在生产服务器上使用交换空间。

根据我的经验,旋转磁盘的交换空间会使系统变得不可预测,并更容易导致整个系统崩溃,令人沮丧。一个负载高、受欢迎的服务器如果与本地慢速磁盘进行任何操作,很快就会陷入比故障状态更糟糕的情况。响应时间将增加到正常水平的100倍,简单的事情,如通过控制台或ssh登录可能需要几分钟。

SSD交换空间是一个特殊情况,至少可以消除通常会导致系统崩溃的寻道时间延迟。然而,写入仍然很慢,所以您仍然需要等待很长时间才能从失控的进程中恢复过来。

没有交换空间,您的LAMP服务器将简单地终止进程以释放RAM。适当的监控应该会提醒您,并在关键进程被终止时将服务器从生产环境中移除。最坏的情况是,您的登录方法都被终止了,您不得不进行硬重置/电源循环。这种最坏的情况在失控的交换机器上同样可能发生,但更难以检测。

如果您使用PHP,请启用内存限制,并监视日志以查看其故障。这是一个技巧,在开发服务器上将限制设置得比生产环境更低。如果您在Apache下使用mod_php,请将MaxRequestsPerChild设置为几千,以便httpd在一段时间后消失之前不会变得太大。最重要的是,监视内存使用情况!通常情况下,内存会随着时间的推移逐渐增加,您只需要在调试问题时定期重新启动一个有泄漏的服务。


1谢谢分享你的经验。我在处理类似问题时也遇到了一些困难,当ssh占用过多内存时。我只是强制限制进程的内存使用,这样就可以运行ssh并修复有问题的脚本了。 - Arman
我在互联网上看到的关于生产环境中交换空间的讨论是最有趣的之一。(整个帖子,利弊) - dpb

交换空间是在您的系统决定需要为活动进程提供物理内存,而没有足够未使用的物理内存可用时使用的。如果系统需要更多的内存资源或空间,物理内存中的非活动页面将被移动到交换空间,从而释放出该物理内存供其他用途使用。
这种情况在服务器上经常发生。
a) 一个非优化的脚本可能会消耗大量内存。 b) 像备份这样的脚本总是会消耗大量内存。 c) 高流量。
因此,拥有一些交换空间是一个好的做法。
更多详细信息:https://help.ubuntu.com/community/SwapFaq

感谢解释。如果一个脚本有问题,那么无论如何都会导致服务器崩溃,系统限制应该控制你的脚本,不是吗? - Arman
aneeshep,如果你在交通繁忙时进行交换,你的系统速度将会比正常情况下慢100倍。这通常是不可接受的。 - SpamapS

使用交换空间将为您提供一种额外的保障,以防止服务器不稳定。有时候内存可能会耗尽,在没有交换空间的服务器上,这可能导致软件崩溃。
我可能是少数人之一,但我认为,仍然有意义,就像他们过去建议的那样,将交换空间设置为主内存的两倍。即使在拥有96GB内存的系统上也是如此。
这并不花费太多,如果有一天需要它,您会庆幸自己已经准备好了。启用交换空间的原因只是一个非常直接的成本效益分析。赶紧行动吧!:-)

我想感谢Oli提供的精彩答案,虽然我知道这是老问题。分区是一个永远热门的话题! 我完全同意Oli帖子中的观点,并且我想分享一下我使用的脚本来监控服务器的交换空间使用情况(当然还有改进的空间)。
我总是将服务器和服务配置为根本不会发生交换。如果发生了交换,那么肯定是出了问题,或者至少是超出了最初的计划。
在生产环境中,我每隔半小时就会在crontab中运行这个脚本。 如果交换使用量不等于0k,它会发送通知给我。 这样我就能够及时调查/采取措施解决问题,大多数情况下,是在事情真正变得糟糕之前。
需要你拥有:bash、top、echo、awk以及一个可用的邮件命令,而不进行任何检查。
希望对你有所帮助。
#!/bin/bash
CURRSWAP=$(top -b -n1 |grep Swap |awk '{print $4}')
ECOMM="echo $CURRSWAP means healthy, I wont take any action."
CURRDATE=$(date)
MAILDST="your@email.addr"

case $CURRSWAP in
  [0]k) $ECOMM
        exit 0
        ;;
  *)    echo -e "Server: $HOSTNAME \n Date: $CURRDATE \n Current Swap partition usage: $CURRSWAP" | mail -s "Warning from $HOSTNAME" -- $MAILDST
        exit 0
        ;;
esac
exit 0