优化基于Kohana的网站以提高速度和可扩展性

Sam*_*son 80 php optimization performance scalability kohana

我与Kohana建立的网站昨天遭到了大量的流量冲击,导致我退后一步并评估一些设计.我很好奇什么是优化基于Kohana的应用程序的标准技术?

我也对基准测试感兴趣.我是否需要设置Benchmark::start()Benchmark::stop()使用每个控制器方法才能查看所有页面的执行时间,或者我是否能够全局且快速地应用基准测试?

我将在未来更多时间使用Cache-library,但我愿意接受更多建议,因为我确信我能做很多事情,我现在根本不知道.

Pas*_*TIN 211

我在这个答案中所说的并不是Kohana特有的,并且可能适用于许多PHP项目.

在讨论性能,可伸缩性,PHP时,我想到了以下几点:我
在处理多个项目时使用了很多这些想法 - 他们帮助了; 所以他们也可能在这里帮忙.


首先,在表演方面,有许多方面/问题需要考虑:

  • 服务器的配置(Apache,PHP,MySQL,其他可能的守护进程和系统) ; 我想,你可能会在ServerFault上得到更多的帮助,
  • PHP代码,
  • 数据库查询,
  • 使用或不使用您的网络服务器?
  • 你能使用任何一种缓存机制吗?或者您是否需要在网站上提供更多最新数据?


使用反向代理

第一件可能真正有用的事情是在你的网络服务器前面使用反向代理,比如清漆:让它尽可能多地缓存,所以只有真正需要PHP/MySQL计算的请求(当然还有其他一些)请求,当它们不在代理的缓存中时)进入Apache/PHP/MySQL.

  • 首先,你的CSS/Javascript/Images - 好吧,一切都是静态的 -可能不需要总是由Apache提供
    • 因此,您可以使用反向代理缓存所有这些.
    • 提供这些静态文件对于Apache来说并不是什么大不了的事,但是对它们来说工作的越少,它就越能用PHP做.
    • 请记住:Apache一次只能处理有限的,有限数量的请求.
  • 然后,让反向代理从缓存中尽可能多地使用PHP页面:可能有些页面经常不会更改,并且可以从缓存中提供.而不是使用一些基于PHP的缓存,为什么不让另一个更轻的服务器服务(并且不时从PHP服务器获取它们,所以它们总是几乎是最新的)
    • 例如,如果您经常请求一些RSS提要(我们通常倾向于忘记那些,在尝试优化性能时),将它们放在缓存中几分钟可以节省数百/数千个请求到Apache + PHP + MySQL的!
    • 对于您网站访问量最大的页面,如果它们至少在几分钟内没有更改(例如:主页?),则每次用户请求时都不需要浪费CPU重新生成它们.
  • 也许为匿名用户提供的页面(所有匿名用户的相同页面)和为已识别用户提供的页面之间存在差异(例如,"Hello Mr X,您有新消息")
    • 如果是这样,您可以配置反向代理来缓存为匿名用户提供的页面(基于cookie,通常是会话cookie)
    • 这意味着Apache + PHP处理的次数较少:只识别用户 - 这可能只是用户的一小部分.

关于使用反向代理作为缓存,对于PHP应用程序,您可以查看基准测试结果显示使用APC和Squid缓存增加400%-700%的服务器功能.
(是的,他们正在使用Squid,而我正在谈论清漆 - 这只是另一种可能性^^ Varnish更新,但更专注于缓存)

如果你做得那么好,并设法一次又一次地停止重新生成太多页面,也许你甚至不必优化你的任何代码;-)
至少,也许不是任何一种急于...当你没有太多的压力时,进行优化总是更好......


作为旁注:你在OP中说:

我和Kohana建造的一个网站昨天遭到了大量的交通抨击,

这是一种突然的情况,如果你的网站可以处理第二个不是最新的反向代理,那么反向代理可以真正地节省一天:

  • 安装它,配置它,让它始终- 每个正常的一天 -运行:
    • 将其配置为不将PHP页面保留在缓存中; 或者只持续一小段时间; 这样,您始终可以显示最新数据
  • 而且,你采取slashdot或digg效果的那一天:
    • 配置反向代理以将PHP页面保留在缓存中; 或者更长的时间; 也许你的页面不会在第二天更新,但它会让你的网站在挖掘效果中存活下来!

关于这一点,我怎样才能发现并成为"Slashdotted"?可能是一个有趣的读物.


在PHP方面:

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

请注意,性能是使用PHP 5.3的一个很好的理由(我已经做了一些基准测试(法语),结果很棒) ...
另一个很好的理由当然,PHP 5.2已经达到了它的使用寿命,不再维护了!

你在使用任何操作码缓存吗?

  • 我正在考虑APC - 替代PHP缓存,例如(pecl,manual),这是我见过的最常用的解决方案 - 并且用于我工作的所有服务器上.
  • 在某些情况下,它可以真正降低服务器的CPU负载(我已经看到一些服务器上的CPU负载从80%上升到40%,只需安装APC并激活它的操作码缓存功能!)
  • 基本上,PHP脚本的执行分为两个步骤:
    • 将PHP源代码编译为操作码(相当于JAVA的字节码)
    • 执行那些操作码
    • APC将这些内容保存在内存中,因此每次执行PHP脚本/文件时都需要完成的工作量较少:只从RAM中获取操作码并执行它们.
  • 你可能需要看看APC的配置选项,顺便说一句
    • 其中有很多,有些可以对速度/ CPU负载/易用性产生很大影响
    • 例如,禁用[apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)可以有利于系统负载; 但这意味着除非你刷新整个操作码缓存,否则不会考虑对PHP文件所做的修改; 关于这一点,有关更多详细信息,请参阅例如To stat()或Not To stat()?


使用缓存来处理数据

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

我正在考虑的主要事情当然是SQL查询:你的许多页面可能会执行相同的查询,其中一些查询的结果可能几乎总是相同的......这意味着许多"无用的"查询制作到数据库,必须花时间反复提供相同的数据.
当然,对于其他的东西也是如此,例如Web服务调用,从其他网站获取信息,繁重的计算,......

您可能会非常感兴趣地确定:

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

并将这些数据/结果存储在某种缓存中,因此它们更容易获得 - 更快 - 而且您不必为了"没有"而去SQL服务器.

例如,伟大的缓存机制是:

  • APC:除了我之前谈过的操作码缓存之外,它还允许你将数据存储在内存中,
  • 和/或memcached (另请参阅),如果您确实拥有大量数据和/或使用多个服务器,则它非常有用,因为它是分布式的.
  • 当然,你可以考虑文件; 可能还有很多其他的想法.

我很确定你的框架附带了一些缓存相关的东西; 你可能已经知道了,正如你所说的那样"我将在OP中更多地使用Cache-library" ;-)


剖析

现在,一件好事就是使用Xdebug扩展来分析你的应用程序:它通常可以很容易地找到几个弱点 - 至少,如果有任何函数需要花费很多时间.

如果配置正确,它将生成可以使用某些图形工具分析的分析文件,例如:

  • KCachegrind:我最喜欢的,但仅适用于Linux/KDE
  • Wincachegrind for windows; 不幸的是,它比KCacheGrind少了一些东西 - 它通常不会显示调用图.
  • Webgrind在PHP Web服务器上运行,因此可以在任何地方运行 - 但可能具有较少的功能.

例如,以下是KCacheGrind的几个屏幕截图:

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

(顺便说一下,第二个屏幕截图上显示的调用图通常是WinCacheGrind和Webgrind都不能做的事情,如果我没记错的话^^)


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

您应该能够使用它alonside XHGui,这将有助于数据的可视化.


在SQL方面:

现在我们已经谈了一些关于PHP的内容,请注意,你的瓶颈可能不是PHP方面的东西,而是数据库中的...

这里至少有两三件事:

  • 你应该确定:
    • 您的应用程序最常见的查询是什么
    • 如果使用MySQL,是否优化了(使用正确的索引,主要是?),使用EXPLAIN指令
    • 是否可以缓存其中的一些查询(请参阅我之前说过的内容)
  • 你的MySQL配置得好吗?我对此并不了解,但有一些配置选项可能会产生一些影响.

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

  • 如果您不需要,请不要访问数据库:尽可能多地缓存!
  • 当您必须转到数据库时,请使用有效的查询:使用索引; 和个人资料!


现在怎么办?

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

嗯,仍然有改进的余地......一些面向架构的想法可能是:

  • 切换到n层架构:
    • 将MySQL放在另一台服务器上(2层:一台用于PHP;另一台用于MySQL)
    • 使用多个PHP服务器(并在这些服务器之间对用户进行负载平衡)
    • 使用其他计算机作为静态文件,使用较轻的Web服务器,例如:
    • 使用几个服务器用于MySQL,几个服务器用于PHP,以及几个反向代理
    • 当然:在任何具有任意数量空闲RAM的服务器上安装memcached守护进程,并使用它们尽可能多地进行缓存.
  • 使用Apache更"高效"的东西?

好吧,也许有些想法在你的情况下有点矫枉
过来^^ 但是,仍然......为什么不研究它们,以防万一?;-)


那么Kohana呢?

你最初的问题是关于优化使用Kohana的应用程序......好吧,我已经发布了一些适用于任何PHP应用程序的想法 ......这意味着它们对于Kohana也是如此;-)
(即使不是特定于它^^)

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

我还说你不应该做任何不必要的事情; 你不需要Kohana默认启用的任何东西吗?
浏览网络,似乎至少有一些关于XSS过滤的东西; 你需要那个吗?

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


结论?

最后,一个简单的想法:

  • 贵公司支付5天的费用是多少? - 考虑到进行一些很好的优化是合理的时间
  • 您的公司购买(支付?)第二台服务器及其维护费用是多少?
  • 如果你需要扩大规模怎么办?
    • 花10天花多少钱?更多?优化应用程序的每个可能位?
    • 多少台服务器多少钱?

我不是说你不应该优化:你绝对应该!
但是要进行"快速"优化,首先会获得大奖励:使用一些操作码缓存可以帮助您获得服务器CPU负载的10%到50%......并且设置只需要几分钟; - )另一方面,花费3天时间为2%......

哦,顺便说一下:在做任何事情之前:把一些监控的东西放在适当的位置,这样你就知道已经做了哪些改进,以及如何改进!
如果没有监控,你将不知道你做了什么的效果......即使它是真正的优化也不是!

例如,你可以使用类似RRDtool + cacti的东西.
并向你的老板展示一些带有40%CPU负载下降的漂亮图形总是很棒;-)


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

  • 这是多么愚蠢的回答,特别是与其他帖子相比. (17认同)
  • 很棒的解释!你有可以订阅的博客吗?:-) (16认同)
  • +1:很好的解释,这适用于所有项目.谢谢 (2认同)

Kor*_*nel 5

使用XDebug的配置文件代码.

使用大量缓存.如果您的页面是相对静态的,那么反向代理可能是最好的方法.


ae.*_*ae. 5

除了使用数据库对象外,Kohana开箱即用非常快.引用Zombor"您可以通过确保使用数据库结果对象而不是结果数组来减少内存使用量." 这使得HUGEE在被抨击的网站上的性能差异.它不仅使用更多内存,还会降低脚本执行速度.

此外 - 您必须使用缓存.我更喜欢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;
}
Run Code Online (Sandbox Code Playgroud)

这也将大大提高性能.上述两种技术将站点性能提高了80%.

如果你提供了一些关于你认为瓶颈在哪里的更多信息,我相信我们可以给出一些更好的想法.

另请查看yslow(google it)以获取其他一些性能提示.