优化 VPS 上运行的 apache/php/mysql 以应对高负载

优化 VPS 上运行的 apache/php/mysql 以应对高负载

关于在具有 512m RAM 的 VPS 上优化 apache/mysql 服务器的问题。在正常负载下,一切都运行迅速,没有连接延迟。但是,当我们遇到流量大的日子(访问量超过 50k 次)时,网站会爬行,需要 30 秒以上才能从 apache 获取内容。

该网站在 Expression Engine (CMS)(PHP 版)上运行,我遵循了他们的重负载优化指南。我在 Google 上搜索并遵循了不少有关 Apache 的指南,运气不错,终于达到了现在的状态,但我需要获得恒定的响应时间。

我认为这与这里的“针对低内存进行优化”问题不同,因为我有足够的 RAM(对于我想做的事情),我只需要让服务器在高负载下不出现拥塞。

有什么建议吗?

答案1

对于 PHP 来说,有 2 件重要的事情可以增加容量:

  1. 高级 PHP 缓存(APC)正如所提到的。这是我们在雅虎使用的。还有其他类似的项目,但这个项目是 Rasmus 的心血之作。
  2. 快速CGI而不是 mod_php。这个问题存在争议,因为 mod_php 通常是最快的。但是,我假设您有一个 Apache 服务器,它同时提供动态 PHP 内容和静态资产(JS、CSS、flash、图像、PDF 等)。这些静态资产的请求不需要消耗太多内存,但由于 PHP 是一个模块,因此它存在于每个 Apache 线程中。

对于 Apache:

  1. 使用工人 MPM
  2. 使能够活着

您也可以考虑从 Apache 切换到Lighttpd, 或者Nginx。我喜欢 Apache。我充分利用了它的许多高级功能。我接受它的开销,因为我需要它提供的功能。对于常见的 LAMP 堆栈,它超出了需要的范围,浪费资源。

对于 MySQL:

  1. 如果将优化工作花在分析和更正查询上,而不是调整 my.cnf 值,那么您的回报将是 10 倍。我并不是说正确设置缓存、连接等不重要……但对于大多数人来说,这只是问题的 9%。
  2. 在 QA 期间,打开通用查询日志在您的 staging/dev mysqld 上捕获所有发送的查询。(请勿在您的生产 mysql 服务器上执行此操作!)
  3. 使用解释分析查询。特别是如果您使用的是带有 ORM 的框架(抽象 DB 并阻止您编写自己的 SQL),您将需要清除多余的 JOIN、没有 WHERE 子句的 SELECT、导致“使用文件排序”的 ORDER BY 以及不使用索引的查询。
  4. 如果你使用的是 MySQL 5.1利用查询分析器

其他值得考虑的工具包括mk-visual-解释

我引用了 10 个很棒的参考资料。这些东西应该会让你兴奋不已。请让我们知道结果如何。

答案2

将您的 PHP 会话文件移动到临时文件,使用 APC (或其他)并删除全部您不需要的 PHP 模块。删除全部您不需要/不使用的 Apache 模块。

创建 tmpfs(RAM 中的目录!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs

/etc/fstab添加下面的行以便在重启时创建它!

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0

/etc/apache2/php.ini调整将您的会话存储在 RAM(tmpfs)中!

session.save_handler = files
session.save_path = "/tmpfs"

注意:由于您的 PHP 文件和会话文件都在 RAM 中,因此您几乎不会触碰磁盘!

使用expires_module在 apache 中浏览器会缓存大多数东西。

ExpiresActive On
ExpiresDefault "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/ico "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType text/css "Access plus 90 days"
ExpiresByType text/html "Access plus 90 days"
ExpiresByType application/x-shockwave-flash "Access plus 90 days"
ExpiresByType application/x-javascript "Access plus 90 days"

不要使用 .htaccess文件!相反,将它们硬编码到 vhost 配置文件中!将大大消除/减少所有 http 请求的磁盘检查……这确实很有效。

Options FollowSymLinks 
AllowOverride None

例子在您的 vhost.conf 文件中使用的 .htaccess...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>

答案3

我想到了一些事情。

操作码缓存始终是个好主意。我更喜欢http://eaccelerator.net/超过 APC。如果你一直没有使用 APC 进行开发,那么尝试添加它几乎总是很痛苦。Eaccelerator 虽然不那么花哨,但似乎可以工作。

反向代理也是一个好主意,但您需要注意 RAM 的使用情况。我发现带有 mpm-worker 的 Apache 2.2 本身就占用了相当多的 RAM。对于您,我建议使用 Nginx 等更轻量级的程序,并以 FASTCGI 形式运行带有 PHP 的 Apache,或者只是将其保留为进程。使用 Varnish、Squid、Nginx 等的想法是让它们提供静态内容、处理用户连接,并仅将 PHP 请求传递给您视为应用程序服务器的 Apache。

如果您运行的是较新版本的 Mysql 5.1,例如至少 5.1.24,您现在可以访问亚秒级慢速日志。我会将 long_query_time 设置为 1 或 2,然后在您处理真正较长的日志时将其降低到 0.5。网络上还有许多有关 Mysql 的常规调优信息,但您没有足够的 RAM 来做很多事情。您是否增加了任何默认设置?大多数默认 my.cnf 文件配置为使用大约 64MB 的 RAM。我至少会将 key_buffer 从 16MB 提高到 64MB。

此外,您使用的是 Myisam 还是 Innodb 表?如果您将会话保留在数据库中,则需要将会话表更改为 Innodb(或改为 cookie),而不是将其保留为执行表级锁定而不是行级锁定的 Mysiam 表。基本上,任何写入率超过 20% 且读取率超过 80% 的表都适合迁移到 Innodb。请记住,您需要在 Myisam 表和 Innodb 表之间平衡 RAM 量,因为每个表的缓冲区都是单独配置的。

最后,如果价格更便宜或大致相同,那么在您的设置中再增加 512MB RAM 或甚至增加另一个 512MB VPS 来运行 Mysql 会大有帮助。我实际上更倾向于使用第二个实例,因为这将使可用的磁盘 IO 翻倍。VPS 服务器的一个问题是您的 IO 不受同一物理服务器上其他人的保护。

嗯,我的帖子有点杂乱无章,但给你提供了许多可以参考的地方。祝你好运。

答案4

在内存较低的情况下(对于高流量服务器来说,512Mb 较低),值得考虑选择 Web 服务器和 DB 引擎。

Lighttp 比 Apache 经过大量调整后通常能做到的更轻量,甚至还有更轻量级的选项。当然,如果您依赖的 Apache 功能在其他服务器中不受支持,这是不可能的。

sqlite 比 mySQL 更紧凑,而且在很多情况下也更快。请检查您使用的引擎是否也支持此功能,如果支持,请尝试一下。

另一个选择,也是简单的选择,就是如果您负担得起的话,在虚拟机中获取更多 RAM。

相关内容