优化 apache/php/mysql 重载运行在 VPS 上

Par*_*ots 17 mysql optimization vps apache-2.2

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

该站点在 Expression Engine (CMS)(在 PHP 中)上运行,我遵循了他们的重载优化指南。我已经在谷歌上搜索并跟踪了很多 apache 并幸运地找到了它现在的位置,但我需要获得恒定的响应时间。

我认为这与此处的“优化低内存”问题不同,因为我有足够的 RAM(对于我正在尝试做的事情),我只需要让服务器在重负载下不阻塞。

有什么建议吗?

Bru*_*sky 19

对于 PHP,有两个重要的事情可以增加容量:

  1. 如前所述,高级 PHP 缓存(APC)。这就是我们在 Yahoo! 使用的内容。还有其他类似的项目,但这是 Rasmus 的宝贝。
  2. FastCGI而不是 mod_php。关于这个问题存在争议,因为 mod_php 通常是最快的。但是,我假设您有一个 Apache 服务器,可同时提供动态 PHP 内容和静态资产(JS、CSS、Flash、图像、PDF 等)。对这些静态资产的请求不需要消耗那么多内存,但是因为 PHP 是一个模块,所以它存在于每个 Apache 线程中。

对于阿帕奇:

  1. 使用工人 MPM
  2. 启用KeepAlive

您也可以考虑从 Apache 切换到LighttpdNginx。我爱阿帕奇。我使用了它的许多高级功能的傻瓜。我接受它的开销,因为我需要它提供的东西。对于普通的 LAMP 堆栈来说,它是多余的,而且是一种资源浪费。

对于 MySQL:

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

其他值得考虑的工具是mk-visual-explain

我引用了 10 篇很好的参考文献。这些东西应该让你嗡嗡作响。请让我们知道结果如何。


Nul*_*led 6

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

创建一个 tmpfs(RAM 中的一个目录!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs
Run Code Online (Sandbox Code Playgroud)

/etc/fstab 中添加以下行以在重新启动时创建它!

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0
Run Code Online (Sandbox Code Playgroud)

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

session.save_handler = files
session.save_path = "/tmpfs"
Run Code Online (Sandbox Code Playgroud)

注意:使用 RAM 中的 PHP 文件和会话文件,您几乎不会接触磁盘!

在 apache 中使用expires_module以便浏览器缓存大部分内容。

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"
Run Code Online (Sandbox Code Playgroud)

不要使用 .htaccess文件!相反,在 vhost 配置文件中对它们进行硬编码!将彻底消除/减少每个 http 请求的磁盘检查......它真的加起来了。

Options FollowSymLinks 
AllowOverride None
Run Code Online (Sandbox Code Playgroud)

vhost.conf 文件中使用的 .htaccess示例...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>
Run Code Online (Sandbox Code Playgroud)


kas*_*ani 5

想到了几件事。

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

反向代理也是一个好主意,但您需要注意 RAM 使用情况。我发现带有 mpm-worker 的 Apache 2.2 自己占用了大量的 RAM。在你的情况下,我会推荐像 Nginx 这样更轻的东西,并用 PHP 作为 FASTCGI 运行 Apache,或者只是按照进程保留它。使用 Varnish、Squid、Nginx 等的想法是让它们提供静态内容,处理用户连接,并且只将 PHP 请求传递给您作为应用程序服务器对待的 Apache。

如果您正在运行 Mysql 5.1 的最新版本,例如至少 5.1.24,您现在可以访问亚秒级慢日志。我会从 1 或 2 开始 long_query_time,然后在您处理真正长的时将其降低到 0.5。网上也有很多关于 Mysql 的一般调优信息,但你没有足够的内存来做很多事情。您是否从默认设置中增加了任何设置?大多数默认 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 不受同一物理服务器上其他人的保护。

嗯,我的帖子有点散漫,但给了你很多看的地方。祝你好运。