优化Kohana网站的速度和可扩展性

我和Kohana一起build造的一个地方昨天遭到了大量的交通,让我退后一步,评估一些devise。 我很好奇什么是一些优化Kohana应用程序的标准技术?

我也对基准感兴趣。 我是否需要为每个控制器方法设置Benchmark::start()Benchmark::stop() ,以便查看所有页面的执行时间,还是能够快速地应用基准testing?

我会更及时地使用Cache-library,但是我可以提供更多的build议,因为我确信有很多我可以做的事情,目前我根本没有意识到。

我会在这个答案中说的不是特定于Kohana,可能适用于大量的PHP项目。

在谈论性能,可伸缩性,PHP,…时,我想到了一些要点。
我在处理好几个项目的时候使用了很多这样的想法, 所以他们也可能在这里帮助。

首先,在演出方面 ,有很多方面需要考虑

  • 服务器的configuration(Apache,PHP,MySQL,其他可能的守护进程和系统) ; 你可能会得到更多关于ServerFault的帮助,我想,
  • PHP代码,
  • 数据库查询,
  • 使用或不使用您的networking服务器?
  • 你可以使用任何一种caching机制? 或者你需要更多的网站上最新的数据?

使用反向代理

第一件事可能是非常有用的,就是在你的web服务器前面使用一个反向代理varnish) :让它caching尽可能多的东西 ,所以只需要真正需要PHP / MySQL计算的请求(当然还有其他的请求,当他们不在代理的caching),使其到Apache / PHP / MySQL的。

  • 首先,你的CSS / Javascript /图像– 一切都是静态的 –可能不需要总是由Apache来服务
    • 所以,你可以让反向代理caching所有这些。
    • 提供这些静态文件对于Apache来说并不是什么大不了的事情,但是为这些静态文件工作的人越less,使用PHP就能做的越多。
    • 请记住:Apache一次只能服务一个有限数量的请求。
  • 然后,让反向代理尽可能多地从caching中提供PHP页面:可能有些页面不会经常更改 ,并且可能从caching中提供。 为什么不让另一个更轻的服务器为它们提供服务(并且不时从PHP服务器获取它们,所以它们总是几乎是最新的)
    • 例如,如果您有一些RSS提要(我们通常倾向于忘记那些需要经常 优化性能的提要 ,让他们在caching中几分钟就可以节省成千上万的对Apache + PHP的请求+ MySQL的!
    • 如果网站访问量最大的网页是相同的,如果它们至less在几分钟内没有变化(例如:首页?) ,那么每次用户请求时都不必浪费CPU重新生成它们。
  • 也许匿名用户的页面(所有匿名用户的同一页面)和为已识别用户提供的页面(例如,“您好,X先生,您有新消息”)之间是有区别的?
    • 如果是这样的话,您可以configuration反向代理来caching为匿名用户提供服务的页面(通常基于cookie,如会话cookie)
    • 这意味着Apache + PHP的处理更less:只有被识别的用户 – 这可能只是用户的一小部分。

关于使用反向代理作为caching ,对于PHP应用程序,例如,您可以考虑使用APC和Squidcaching基准testing结果显示400%-700%的服务器function增加
(是的,他们正在使用鱿鱼,而我正在谈论清漆 – 这只是另一种可能性^^清漆是最近的,但更致力于caching)

如果你做得够好,并设法停止重复生成太多的网页,也许你甚至不需要优化你的任何代码;-)
至less,也许不会有任何一种匆忙……当你没有太多的压力时,最好是进行优化。

作为一个旁注:你在OP中说:

我和Kohana一起build造的一个地方昨天被猛烈的交通撞上了,

这是一种突如其来的情况,一个反向代理可以从字面上节省一天 ,如果你的网站可以处理不是第二个最新的:

  • 安装它,configuration它,让它永远– 每一天正常运行:
    • 将其configuration为不将PHP页面保留在caching中; 或者只持续很短的时间; 这样,你总是有最新的数据显示
  • 而且,当你使用slashdot或digg的效果:
    • configuration反向代理以将PHP页面保存在caching中; 或更长的一段时间; 也许你的网页第二次不会被更新,但它可以让你的网站在digg-effect中生存下来!

关于这一点, 我怎么能检测和生存是“Slashdotted”? 可能是一个有趣的阅读。

在PHP的一面:

首先:你使用的是最近版本的PHP吗? 有定期改进的速度,与新版本;-)
例如,看看PHP分支3.0到5.3-CVS的Benchmark

请注意,性能是一个很好的理由使用PHP 5.3 ( 我做了一些基准(法语) ,结果是伟大的)
另一个很好的理由是,当然,PHP 5.2已经到了它的终结,而不再被维护!

你使用任何操作码caching?

  • 我正在考虑APC – Alternative PHP Cache ,例如( pecl , manual ) ,这是我见过的最多的解决scheme,而且在我工作的所有服务器上都使用它。
    • 另见: 幻灯片APC Facebook
    • 基准testing结果显示使用APC和Squidcaching的服务器function增加400%-700%
  • 它可以真正降低服务器的CPU负载,在某些情况下(我已经看到一些服务器的CPU负载从80%上升到40%,只需安装APC并激活它的操作码cachingfunction)!
  • 基本上,PHP脚本的执行分两步进行:
    • 编译PHP源代码到操作码(类似于JAVA的字节码)
    • 执行这些操作码
    • APC将这些内存保存在内存中,因此每次执行PHP脚本/文件时都需要完成的工作量较less:只能从RAM获取操作码并执行它们。
  • 你可能需要看看APC的configuration选项 ,顺便说一句
    • 有相当多的这些,有些可以对你的速度/ CPU负载/易用性有很大的影响
    • 例如,禁用[apc.stat](http://php.net/manual/en/apc.configuration.php#ini.apc.stat)可以很好地用于系统加载; 但这意味着除非你刷新整个操作码caching,否则不会考虑对PHP文件所做的修改; 关于这个,有关更多细节,请参阅To stat()或Not To stat()?

使用caching数据

尽可能避免一遍又一遍地做同样的事情

我正在考虑的主要事情当然是SQL查询:你的许多网页可能做同样的查询,其中一些查询的结果可能几乎总是一样的……这意味着大量的“无用”查询对数据库进行处理,而这些数据库必须花费时间一遍又一遍地处理相同的数据。
当然,对于其他的东西也是如此,比如Web服务调用,从其他网站获取信息,繁重的计算,…

你可能很有兴趣确定:

  • 哪些查询运行很多次,总是返回相同的数据
  • 哪些其他(重)计算大量时间,总是返回相同的结果

并将这些数据/结果存储在某种caching中,这样他们就可以更容易地获得 – 更快 – 而且不必为了“无”而去SQL服务器。

伟大的caching机制,例如:

  • APC :除了前面提到的操作码caching之外,它还允许您将数据存储在内存中,
  • 和/或memcached ( 另请参阅 ) ,这是非常有用的,如果你字面上有大量的数据和/或使用多个服务器 ,因为它是分布式的。
  • 当然,你可以考虑文件; 并可能还有其他许多想法。

我很确定你的框架有一些caching相关的东西; 你可能已经知道,正如你所说的“我将在更多的时候使用Cache-library来”在OP 😉

剖析

现在,做一个好的事情就是使用Xdebug扩展来分析你的应用程序 :它经常可以很容易地find一些弱点 – 至less,如果有任何function需要很多时间。

configuration正确 ,它将生成分析文件,可以使用一些graphics工具进行分析,例如:

  • KCachegrind :我最喜欢的,但只适用于Linux / KDE
  • Wincachegrind for windows; 它比KCacheGrindless了一些东西,不幸的是,它通常不会显示调用图。
  • Webgrind运行在PHPnetworking服务器上,可以在任何地方工作 – 但可能具有较less的function。

例如,下面是KCacheGrind的几个截图:

KCacheGrind:主屏幕so/kcachegrind/kcachegrind-1-small.png KCacheGrind:作为图像导出的调用图http://extern.pascal-martin.fr/so/kcachegrind/ kcachegrind -2- small.png

(顺便说一下,在第二个截图中显示的callgraph通常是WinCacheGrind和Webgrind都无法做到的,如果我没有记错的话^^)

(感谢@Mikushi的评论)另一种可能性,我没有用太多的xhprof扩展名:它也有助于分析,可以生成callgraphs – 但比Xdebug,这意味着你应该能够安装它一个生产服务器。

你应该可以使用它,这将有助于数据的可视化。

在事物的SQL方面:

现在我们已经讲了一些关于PHP的知识,请注意, 你的瓶颈不是PHP的一面 ,而是数据库的一个瓶颈

至less有两三件事情在这里:

  • 你应该确定:
    • 什么是你的应用程序正在做的最频繁的查询
    • 如果你正在使用MySQL,那么是否使用EXPLAIN指令来优化(使用正确的索引 ,主要是?)
      • 另请参阅: 优化SELECT和其他语句
      • 例如,您可以激活log_slow_queries以获取“太多”时间的请求列表,然后开始优化。
    • 是否可以caching这些查询中的一部分(请参阅前面所述)
  • 你的MySQL是否configuration好? 我对此不太了解,但是有一些configuration选项可能会有一些影响。
    • 优化MySQL服务器可能会为您提供一些有趣的信息。

不过,最重要的两件事是:

  • 如果您不需要,请不要去数据库: 尽可能caching
  • 当你不得不去DB时,使用高效的查询:使用索引; 和个人资料!

现在怎么办?

如果你还在阅读,还有什么可以优化?

那么还有改进的空间……一些面向build筑的想法可能是:

  • 切换到n层架构:
    • 将MySQL放在另一台服务器上(2层:一个用于PHP;另一个用于MySQL)
    • 使用多个PHP服务器(并在这些服务器之间进行负载平衡)
    • 使用其他机器的静态文件,与更轻的networking服务器,如:
      • lighttpd的
      • 或者nginx – 这个越来越受欢迎,顺便说一句。
    • 在MySQL中使用多个服务器,在PHP中使用多个服务器,在这些服务器前使用多个反向代理服务器
    • 当然,安装memcached守护进程的任何服务器上都有任意数量的可用RAM,并尽可能使用它们caching/有意义。
  • 使用Apache“更高效”的东西?
    • 我越来越多地听到关于nginx的问题 ,这对于PHP和大量的网站来说应该是非常棒的。 我从来没有用过它,但是你可能会在网上find一些有趣的文章;
      • 例如, PHP性能III – 运行nginx
      • 另请参见: PHP-FPM –与PHP> = 5.3.3捆绑在一起的FastCGIstream程pipe理器 ,它使用nginx做了许多奇妙的事情。

那么,也许这些想法有点矫枉过正^^
但是,仍然…为什么不研究一下,以防万一? 😉

那么Kohana呢?

你最初的问题是关于优化一个使用Kohana的应用程序……那么,我已经发布了一些适用于任何PHP应用程序的想法 …这意味着他们对于Kohana也是如此;-)
(即使不具体到^^)

我说:使用caching; Kohana似乎支持一些caching的东西 (你自己谈论过,所以这里没有新东西…)
如果有什么可以快速完成的,试试吧;-)

我也说你不应该做任何不必要的事情; 在Kohana中是否有默认启用的东西,你不需要?
浏览networking,似乎至less有一些关于XSS过滤; 你需要吗?

不过,这里有几个可能有用的链接:

  • Kohana一般性讨论:caching?
  • 社区支持:网站优化:使用Kohana最大化网站性能

结论?

总而言之,一个简单的想法是:

  • 贵公司花费5天多less钱? – 考虑到做一些很棒的优化是合理的
  • 第二台服务器需要花费多less钱?
  • 如果你不得不扩大规模呢?
    • 花10天花费多less钱? 更多? 优化应用程序的每一个可能的位?
    • 多less多一台服务器?

我不是说你不应该优化:你绝对应该!
但是要进行“快速”优化,首先会获得丰厚的回报 :使用某些操作码caching可能会帮助您将服务器的CPU负载降低10%到50%…而且只需几分钟即可完成设置; )另一方面,花费3天2%…

哦,而且,顺便说一句:在做任何事情之前: 把一些监控的东西 ,所以你知道已经做了什么改进,以及如何!
没有监控,你将不知道你做了什么的效果…即使这是一个真正的优化或不!

例如,你可以使用类似RRDtool + cacti的东西。
向40%的CPU负载下降显示你的老板一些不错的graphics总是伟大的;-)

无论如何,真正的结论是: 玩得开心!
(是的,优化是有趣的!)
(呃,我不认为我会写那么多…希望至less有一部分是有用的…我应该记住这个答案:其他时候可能会有用…)

使用XDebug和WinCacheGrind或WebCacheGrind来分析和分析执行速度较慢的代码。

WebCacheGrind http://jokke.dk/media/2008-webgrind/webgrind_small.png WinCacheGrind

configuration文件代码与XDebug 。

使用大量的caching。 如果你的页面是相对静态的,那么反向代理可能是最好的办法。

除了使用数据库对象之外,Kohana非常快速。 引用Zombor“通过确保使用数据库结果对象而不是结果数组,可以减less内存使用量。 这使得一个正在被抨击的网站上的巨大的性能差异。 它不仅使用更多的内存,而且减慢了脚本的执行速度。

另外 – 你必须使用caching。 我更喜欢memcache,并在我的模型中使用它:

 public function get($e_id) { $event_data = $this->cache->get('event_get_'.$e_id.Kohana::config('config.site_domain')); if ($event_data === NULL) { $this->db_slave ->select('e_id,e_name') ->from('Events') ->where('e_id', $e_id); $result = $this->db_slave->get(); $event_data = ($result->count() ==1)? $result->current() : FALSE; $this->cache->set('event_get_'.$e_id.Kohana::config('config.site_domain'), $event_data, NULL, 300); // 5 minutes } return $event_data; } 

这也将大大提高性能。 上述两项技术使网站性能提高了80%。

如果您提供了更多关于您认为瓶颈的信息,我相信我们可以提出一些更好的想法。

另外检查yslow(谷歌)的一些其他性能提示。

与Kohana严格相关(你可能已经做了这个,不然):

在生产模式下:

  1. 启用内部caching(这将只cachingKohana :: find_file结果,但这实际上可以帮助很多。
  2. 禁用分析器

只是我2美分:)

我完全同意XDebug和caching的答案。 不要直视Kohana图层进行优化,直到find最大的速度和规模瓶颈。

XDebug会告诉你,你花了大量的时间,并确定你的代码中的“热点”。 保留此分析信息,以便您可以基线和衡量性能改进。

示例问题和解决scheme:如果您发现每次都从数据库中构build昂贵的对象,而且这些对象并不经常更改,那么可以使用memcached或其他机制来caching它们。 所有这些性能修复都需要时间并增加系统的复杂性,因此在开始修复之前请确保您的瓶颈。