it-swarm.cn

如何减少Unix Web服务器上的内存使用量

我目前正在使用Joyent Accelerator来托管我的Web应用程序,并且运行良好,但是我需要降低成本,因此我正在降低当前计划的等级,并强加了一些新的内存限制(256M rss,512M交换)。昨天我对它们并不太远,但是今天重新启动了几次Apache之后,我现在是411M rss,721M swap(prstat -Z -s cpu)。

在Server Fault中搜索仅给我提供了许多方法和特定工具来监视服务器,但没有有关如何减少/优化其内存使用的建议。我也看到过 这个问题 ,但是我认为这对这种特殊(或者我可以说泛型?)情况没有好处。

该服务器在共享CPU上运行Solaris,并且我使用的是Apache + MySQL + PHP堆栈。

我很想知道一个人可以采取的措施来解决这个问题并解决问题。但是,我也没有时间来降低内存占用并在当前计划结束之前降低计划的质量,因此,任何可以创造奇迹并节省时间的事情也都受到欢迎:)

36
lima

感谢大家的回答!按照您的建议,我已经能够将内存使用量减少到195M SWAP和108M RSS,而无需改动我的代码(我很快会对其进行优化) ,但这应该是让我快速摆脱困境的解决方案)。

这是我所做的事情的清单:

摆脱了VirtualHost条目中使用的通配符。我使用服务器的真实IP代替*:80和*:443。

更改了Apache的prefork MPM。这些是我最终使用的值:

 StartServers 1 
 MinSpareServers 1 
 MaxSpareServers 5 
 ServerLimit 16 
 MaxClients 16 
 MaxRequestsPerChild 0 
 ListenBacklog 100 

这些绝不是神奇的数字。我花了一些时间尝试不同的值和组合,然后针对服务器的实际使用情况对它们进行测试,每个人都应在自己的环境中做同样的事情。作为记录,我的服务器每月收到近200万个pvs,以固定的速率同时为动态页面和资产提供服务-没有digg效果。同样,其目的是减少内存占用,而不是提高性能或HA。

参考:

降低了Apache的KeepAlive。通过将KeepAliveTimeout设置为一个较低的值(在我的例子中为2),我可以期望等待的服务器进程更少与可能不要求更多内容的空闲客户端的连接。

参考: http://httpd.Apache.org/docs/2.0/mod/core.html#keepalivetimeout

删除了MySQL未使用的模块。我添加了skip-innodb到MySQL的my.cnf。大量减少内存消耗。


还有一些我个人无法做到的出色建议:

  • 删除PHP模块。我服务器上的PHP大多数mod已编译,我可能会在其他VPS上尝试自己的最小PHP.
  • 使用php-fastcgi切换到nginx。这是我将很快尝试的另一个好建议,但是现在我不能冒险停机了。
23
lima

我发现 这篇关于Apache和MySQL的低内存配置的文章

在布局低内存配置所需的配置更改时非常有用。我针对自己的情况对它们进行了调整,但是它们应该为您提供找到最适合您的环境所需的工具

6
Kevin Kuphal

您将需要限制正在运行的Apache服务器进程的数量,并且要尽可能接近极限,因此您将无法处理非常高的流量。通常,在正常使用情况下使Web服务器达到最大负荷通常是一个坏主意(tm),因为Web流量在大多数情况下都是不错的,并且流量很低,直到您被鞭打,挖掘或火球之类的东西为止。

主要问题是在任何一点上运行的Apache进程的数量-这里假设是前叉,因为我只部署了PHP应用程序和PHP不是线程安全的,我没有确定工作程序MPM的大小,共享内存中有一些项目,每个进程的内存中有一些项目。

您可以通过省去不需要的共享模块来减少总内存占用。基本上,Apache由大多数主机配置为可以在Sun之下进行几乎所有操作。如果您不使用mod_userdir,则将其从Apache配置中注释掉。请小心删除多少,因为您可能需要某些东西或它们的依赖关系不直观!所有模块都应记录在Apache.org网站上。每个进程的足迹很难缩小。如今,大多数Apache配置仅带有编译的四个基本模块。除了这四个模块之外,大多数内存使用情况来自泄漏或应用程序RAM)这不是有效地垃圾回收,这就是为什么您可能希望将每个进程处理的请求数设置得较低。

真的希望将内存使用率保持在RAM本身,而不要进行交换。交换意味着I /O。I/ O速度很慢,将驱动您的CPU使用率在等待某些东西脱离交换之前,进程阻塞了。

4
Karl Katzke

既然您已经实现了目标,那么这里有一些额外的功能:

由于您删除了所有不必要的php模块,因此对于Apache也可以使用相同的模块。默认情况下(取决于您的安装),Apache会加载很多额外的模块,并且对于日常正常使用而言,其中的大多数并不是真正需要的。例如,有很多身份验证模块始终加载。除非您试图限制带宽使用,否则通常不需要deflate。自动索引和状态记录也值得怀疑。

另外一个是您可以在php.ini中限制可用于php的内存量:memory_limit = xxxM

2
rasjani

对于Apache,请删除不使用的模块,因为它们仅使用额外的内存。对于MySQL,如果不使用innodb/bbdb,请删除它们,然后删除PHP=不需要的模块。

接下来,您应该根据一个进程的大小和要分配给Apache的内存量来配置Apache MaxClients。 MySQL上的最大连接数也一样(我建议使用出色的 MySQL Tuning Primer 脚本。

如果您可以控制PHP)应用程序,请确保它不会使用过多的内存(例如,在变量中,尤其是在静态变量中)。

如果想更进一步,可以用nginx + fcgi安装程序替换Apache + mod_php,这可能会导致进一步的内存减少。

最后一件事-您真的不想在Web服务器上交换。只需一点,即可删除不需要的内容,但是在Web服务器上定期交换将导致网站无响应。

2
yhager

该服务器在共享CPU上运行Solaris,并且我使用的是Apache + MySQL + PHP堆栈。

我没有使用Solaris的经验,但是您可以做的最好的事情就是不要使用Apache/mod_php。

  • 使用php-fastcgi切换到nginx。
  • 重新编译php以使用最少的插件。
  • 摆脱不必要的进程,例如ntpd(使用ntpdate),ftp(使用scp)等...
0
Unknown

您当然可以限制Apache可以分叉的进程数,但是这只能作为对内存使用量的Sudo-hard限制。从较低级别的角度来看,可以使用 plimit 来限制可用于进程的资源。我相信,将此应用到父进程和子进程继承。

但是,从Web服务器配置的角度来看,它可以归结为代码的实际运行方式!但是请记住,使用.htaccess文件之类的小事情比使用中央Apache配置文件要消耗更多的资源(因为每次进入请求时都会读取它们,从而导致更大的开销),这在大型网站中很有意义。

0
Coops

可能有助于随着时间推移而增加内存的一件事是将httpd keepalive设置得较低,但是如果您的应用程序需要更长的生命周期,我会仔细测试。

0
D.F.