优化PHP,MYSQL社区网站性能

时间:2009-11-17 16:11:03

标签: php mysql optimization apc

我拥有一个大约12.000个用户的社区网站(写得很重),单个VPS上有100个并发用户,1Gb ram。负载很少超过3,响应非常好。

目前,一个简单的文件缓存用于存储数据库查询结果,以减轻数据库的负载,但网站仍然可以减慢220多个并发用户(负载测试)。

我怎样才能找出瓶颈是什么?

我认为数据库很好,因为缓存工作正常,但磁盘IO可能会导致问题。每个页面加载有大约10个包含和来自DB或文件缓存的10-20个查询,以及大量的php处理。

我尝试使用memcache而不是文件缓存,但令我惊讶的是,负载测试似乎更喜欢文件缓存。

我计划使用Alternative PHP Cache,但我仍然不太了解缓存是如何失效的。我有一个单独的index.php来处理所有请求。缓存是否会存储每个请求的结果?如果我的一个包含(或缓存中的查询结果)发生变化,它会自动清除缓存吗?

找到瓶颈的其他建议(试过xdebug)?

谢谢, 哈姆雷特

5 个答案:

答案 0 :(得分:5)

  

我计划使用Alternative PHP Cache,   但我还是不太懂   缓存如何失效。我有   一个处理所有的索引index.php   要求。缓存是否会存储   每个请求的结果?   它会自动清除缓存吗?   如果我的一个包括(或查询结果   从缓存中改变?

APC不缓存输出。它缓存您编译的字节码。

基本上,正常的PHP请求如下所示:

  1. PHP文件被解析并编译为字节码
  2. PHP解释器执行字节码
  3. APC缓存第一步的结果,因此您不会一遍又一遍地重新编译/重新编译相同的代码。默认情况下,每次请求时它仍然是stat()你的PHP文件,以查看文件是否已经编译后自修改了文件 - 因此对代码的任何更改都将自动使缓存的副本无效。

    您也可以像使用memcached一样使用APC来存储任意用户数据。但请记住:

    1. memcached服务器可以向多个服务器提供数据; APC中缓存的数据只能在本地使用。更好地从一个memcached盒子到四个服务器提供数据,而不是在每个服务器上的APC中拥有4个数据副本。
    2. 根据我的经验,Memcached更善于处理大量并发写入单个缓存密钥。
    3. APC似乎没有很好地应对其缓存填满。碎片增加,性能下降。
    4. 另外,请注意:除非您设置了某种锁定机制,否则基于文件的缓存可能会因同时写入而损坏。如果您已实现锁定,则可能会成为其自身的瓶颈。 IMO,并发性很棘手 - 让memcached / APC /数据库处理它。

答案 1 :(得分:1)

你提到你用XDebug - 你能做什么?通常,要开始追踪瓶颈,您可以启用对请求的分析,然后在KCacheGrindWinCacheGrind中查看生成的“cachegrind”文件。

至于使用缓存系统,像你这样的动态脚本通常会做这样的事情

  • 从脚本的唯一输入构建缓存“key”
  • 询问缓存系统是否包含该密钥的数据。如果有,你很高兴去!
  • 否则,尽一切努力生成数据,并要求缓存系统将其存储在下一次所需的密钥下。

APC Cache可以通过缓存已解析的PHP代码版本来帮助加快速度。

答案 2 :(得分:0)

MySQL有自己的查询缓存。

您可以将query_cache_size设置为超过0

来启用它

如果查询是逐字重复的,并且不包含某些内容,如非确定性函数,会话变量和其他一些描述here的内容,则查询结果将从缓存中获取:

通过针对任何基础查询发出任何DML操作,使查询的缓存无效。

答案 3 :(得分:0)

我打开并在测试服务器上配置了APC,性能提升了大约400%

300个并发用户,响应时间最长为1.4秒:)很适合开始。


更新

实时服务器测试结果

原件:

没有APC: 220个并发用户,服务器负载20,响应时间5000毫秒

没有APC: 250个并发用户,服务器负载20+,网站不可用

新:

启用APC: 250个并发用户,服务器负载2,响应时间为600毫秒

启用APC: 350个并发用户,服务器负载10,响应时间为1500毫秒

APC启用: 500个并发用户,服务器负载20,响应为5000ms +站点完全正常运行,但有点慢但可以正常使用

感谢您的建议,这是非常好的改进。

由于站点写入很大,因此禁用了查询缓存,因此对于整个表,缓存将不断失效。

答案 4 :(得分:0)

我想说你的数据库很可能是IO绑定的,我不知道究竟是什么“VPS”,但如果它是某种VM,那么几乎可以肯定IO的性能非常差。< / p>

尽快获得真正的硬件;并获得一定数量的内存(1G很小; 16G听起来更合理)。

然后您可以调整数据库以使其正常运行。你的数据总共有多大?如果您可以将所有这些(或大多数)放入数据库缓存(不是狡猾的查询缓存,正确的innodb缓冲池),那么就这样做。

我假设你正在使用innodb引擎;如果是这样,那么将缓冲池设置为足以容纳所有数据 - 如果你没有足够的ram,那就购买更多(不,真的!)。

然后你的数据库查询应该很快,即使它们相当糟糕(是的)。

棘手的是,如果你有一台机器,如何分割mysql和PHP之间的ram使用 - 网络服务器(我假设是Apache),特别是如果你使用prefork和许多MaxClients,可以用尽ram并剥夺你的数据库。

在工作中获得适当的监控(使用趋势),并仔细进行更改并准确记录。