在你回答这个问题之前,我从来没有开发过任何流行到足以达到高服务器负载的东西。请把我当作(唉)一个刚刚登陆地球的外星人,尽管我知道PHP和一些优化技术。


我正在开发一个PHP工具,可以获得相当多的用户,如果它是正确的。然而,虽然我完全有能力开发程序,但当涉及到制作可以处理巨大流量的东西时,我几乎一无所知。所以这里有一些关于它的问题(也可以把这个问题变成一个资源线程)。

数据库

At the moment I plan to use the MySQLi features in PHP5. However how should I setup the databases in relation to users and content? Do I actually need multiple databases? At the moment everything's jumbled into one database - although I've been considering spreading user data to one, actual content to another and finally core site content (template masters etc.) to another. My reasoning behind this is that sending queries to different databases will ease up the load on them as one database = 3 load sources. Also would this still be effective if they were all on the same server?

缓存

我有一个用于构建页面和交换变量的模板系统。主模板存储在数据库中,每当一个模板被调用时,它的缓存副本(html文档)就会被调用。目前,我在这些模板中有两种类型的变量-静态变量和动态变量。静态变量通常是像页面名称,网站的名称-不经常改变的东西;动态变量是在每次页面加载时改变的东西。

我的问题是:

比如说我对不同的文章有评论。这是一个更好的解决方案:存储简单的注释模板,并在每次页面加载时呈现注释(来自DB调用),或者将注释页面的缓存副本存储为html页面——每次添加/编辑/删除注释时,页面都会被重新检索。

最后

有人有任何提示/指针运行一个高负载的PHP网站。我很确定这是一种可行的语言——Facebook和Yahoo!优先考虑——但有什么经验是我应该注意的吗?


当前回答

首先,正如Knuth所说,“过早的优化是万恶之源”。如果你现在不需要处理这些问题,那就不要去做,先专注于交付一些正确工作的东西。也就是说,如果优化不能等待。

试着分析你的数据库查询,找出什么是慢的,什么是经常发生的,并从中提出一个优化策略。

我会研究Memcached,因为很多高负载站点都使用它来有效地缓存所有类型的内容,而且它的PHP对象接口非常好。

在服务器之间分割数据库并使用某种负载平衡技术(例如,在具有必要数据的冗余数据库中生成1到#之间的随机数—并使用该数字确定要连接到哪个数据库服务器)也是提高效率的一种极好的方法。

在过去,对于一些相当高的负载站点,这些方法都非常有效。希望这能帮助你开始:-)

其他回答

我不认为自己会很快从MySQL转换过来——所以我想我不需要PDO的抽象功能。DavidM,谢谢你的文章,它们帮了我很多。

使用Xdebug(推荐使用tj9991)之类的工具对应用程序进行性能分析绝对是必须的。盲目地进行优化是没有意义的。Xdebug将帮助您找到代码中真正的瓶颈,这样您就可以明智地花费优化时间,并修复实际上导致速度变慢的代码块。

如果您正在使用Apache,另一个可以帮助测试的实用程序是Siege。它将帮助您预测服务器和应用程序对高负载的反应,从而真正实现它的运行速度。

任何类型的PHP操作码缓存(如APC或其他)也会有很大帮助。

@Gary

不要使用MySQLi——PDO是“现代的”OO数据库访问层。最重要的功能是在查询中使用占位符。使用服务器端准备和其他优化也足够聪明。

我现在正在看PDO,看起来你是对的-但是我知道MySQL正在为PHP开发MySQLd扩展-我认为是为了成功MySQL或MySQLi -你怎么看?


@Ryan, Eric, tj9991

谢谢你关于PHP缓存扩展的建议——你能解释一下为什么要使用一个而不是另一个吗?我听说过通过IRC的memcached很棒,但从来没有听说过APC -你对它们有什么看法?我认为使用多个缓存系统会适得其反。

我肯定会挑选一些测试人员,非常感谢你的建议。

回复: PDO / MySQLi / MySQLND

@gary

你不能说“不要使用MySQLi”,因为他们有不同的目标。PDO几乎就像一个抽象层(尽管实际上不是),它的设计目的是为了方便使用多个数据库产品,而MySQLi则专门针对MySQL连接。在将PDO与MySQLi进行比较的情况下,说PDO是现代访问层是错误的,因为你的声明暗示了进程已经是mysql -> MySQLi -> PDO,而事实并非如此。

MySQLi和PDO之间的选择很简单——如果你需要支持多个数据库产品,那么就用PDO。如果你只使用MySQL,那么你可以在PDO和MySQLi之间选择。

那么你为什么选择MySQLi而不是PDO呢?见下文……

@ross

You are correct about MySQLnd which is the newest MySQL core language level library, however it is not a replacement for MySQLi. MySQLi (as with PDO) remains the way you would interact with MySQL through your PHP code. Both of these use libmysql as the C client behind the PHP code. The problem is that libmysql is outside of the core PHP engine and that is where mysqlnd comes in i.e. it is a Native Driver which makes use of the core PHP internals to maximise efficiency, specifically where memory usage is concerned.

MySQLnd是由MySQL自己开发的,最近已经登陆到PHP 5.3分支,该分支正在RC测试中,准备在今年晚些时候发布。然后你将能够使用mysqnd与MySQLi…但PDO不行。这将使MySQLi在许多方面(不是所有方面)都有性能提升,如果你不需要像PDO那样的抽象功能,它将成为MySQL交互的最佳选择。

也就是说,mysqnd现在可以在PHP 5.3中用于PDO,因此您可以从ND到PDO的性能增强中获得优势,然而,PDO仍然是一个通用的数据库层,因此不太可能像MySQLi那样从ND的增强中获益。

这里可以找到一些有用的基准,尽管它们是2006年的。你还需要注意类似这个选项的事情。

在MySQLi和PDO之间做出选择时,有很多需要考虑的因素。事实上,除非你的请求数量非常高,否则这并不重要,在这种情况下,使用一个专门为MySQL设计的扩展比使用一个抽象的东西并恰好提供MySQL驱动程序更有意义。

这不是哪一个最好的简单问题,因为每一个都有优点和缺点。您需要阅读我提供的链接,然后做出自己的决定,然后测试并找出答案。我在过去的项目中使用过PDO,它是一个很好的扩展,但我对纯性能的选择是MySQLi与新的MySQLND选项编译(当PHP 5.3发布时)。

我不敢相信居然没有人提到这个:模块化和抽象。如果您认为您的站点将不得不扩展到许多机器,那么您必须这样设计它!这意味着一些愚蠢的事情,比如不要假设数据库在本地主机上。它还意味着一些一开始会很麻烦的事情,比如编写数据库抽象层(像PDO,但要轻得多,因为它只做您需要它做的事情)。

这意味着在一个框架下工作。您将需要对代码进行分层,以便稍后通过重构数据抽象层(例如,通过告诉它某些对象位于不同的数据库中)来获得性能,并且代码不必知道或关心。

最后,要注意内存密集型操作,例如不必要的字符串复制。如果你能保持PHP的内存使用较低,那么你的web服务器就会得到更好的性能,当你采用负载平衡的解决方案时,这是可以扩展的。