在高负载站点中使用PHP的策略


242

在回答这个问题之前,我还没有开发出足以达到高服务器负载的流行方法。将我当作(叹息)刚刚降落在地球上的外星人,尽管它知道PHP和一些优化技术。


我正在用PHP开发一个工具,如果可以的话,它可以吸引很多用户。但是,尽管我完全有能力开发该程序,但在制作可以处理大量流量的东西时却一无所知。因此,这里有一些问题(也可以将这个问题转换为资源线程)。

资料库

目前,我计划在PHP5中使用MySQLi功能。但是,如何设置与用户和内容相关的数据库?我实际上需要多个数据库吗?目前,所有内容都混杂在一个数据库中-尽管我一直在考虑将用户数据分发到一个数据库,将实际内容分发到另一个数据库,最后将核心站点内容(模板母版等)分发到另一个数据库。我这样做的原因是,将查询发送到不同的数据库将减轻它们的负载,因为一个数据库= 3个负载源。如果它们都在同一服务器上,这是否仍然有效?

快取

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

我对此的疑问:

说我对不同的文章有意见。这是一个更好的解决方案:每次页面加载时都存储简单的评论模板并呈现评论(通过DB调用),或者将评论页面的缓存副本存储为html页面-每次添加/编辑/删除评论时页面被重新缓存。

最后

有没有人有任何技巧/指针在PHP上运行高负载站点。我很确定这是一种可行的语言-Facebook和Yahoo! 赋予它很高的优先级-但是我应该注意哪些经验?


9
3.5年后的今天,我什至不记得自己在做什么,我想知道自己认为也很酷:)
Ross

8
让这成为您过早优化的课程:)
Rimu Atkinson

Answers:


89

没有两个站点是一样的。您确实需要使用jmeter和基准测试之类的工具来查看问题点在哪里。您可以花费大量时间进行猜测和改进,但是只有在衡量和比较更改后才能看到真正的结果。

例如,多年来,MySQL查询缓存一直是我们所有性能问题的解决方案。如果您的网站运行缓慢,MySQL专家建议打开查询缓存。事实证明,如果您的写入负载很高,则缓存实际上会崩溃。如果您不进行测试就将其打开,您将永远不会知道。

并且不要忘记,您从未完成过扩展。处理10req / s的站点将需要更改以支持1000req / s。而且,如果您足够幸运,需要支持10,000req / s,那么您的架构也可能看起来完全不同。

资料库

  • 不要使用MySQLi- PDO是“现代” OO数据库访问层。要使用的最重要功能是查询中的占位符。它足够聪明,可以为您使用服务器端准备和其他优化。
  • 您现在可能不想破坏数据库。如果您确实发现一个数据库无法满足需求,则有多种技术可以扩展,具体取决于您的应用程序。如果读取次数多于写入次数,则复制到其他服务器通常效果很好。分片是一种将数据拆分到多台计算机上的技术。

快取

  • 您可能不想缓存在数据库中。数据库通常是您的瓶颈,因此添加更多IO通常是一件坏事。有几个PHP缓存可以完成类似APC和Zend的功能。
  • 启用和禁用缓存来衡量您的系统。我敢打赌,您的缓存比直接提供页面要重。
  • 如果需要很长时间才能从db构建注释和文章数据,请将memcache集成到系统中。您可以缓存查询结果并将其存储在memcached实例中。重要的是要记住,从内存缓存中检索数据必须比从数据库中汇编数据要快得多,以了解任何好处。
  • 如果您的文章不是动态的,或者在生成文章后进行了简单的动态更改,请考虑将html或php写到磁盘上。您可能有一个index.php页面,该页面在磁盘上查找该文章,如果该文章存在,则会将其流式传输到客户端。如果不是,它将生成文章,将其写入磁盘,然后将其发送给客户端。从磁盘上删除文件将导致页面被重写。如果在文章中添加了评论,请删除缓存的副本-它将重新生成。

10
@写入磁盘。您甚至可以放弃index.php并让Apache为您完成工作,因此只有在路径不存在时才调用index.php。您将为此使用mode_rewrite。
troelskn

5
-1,PDO比MySQLi甚至MySQL扩展慢得多。
Alix Axel

4
PDO比mysqli慢得多,并且不适用于我的嵌套查询。Mysqli也像PDO一样支持服务器端准备和绑定参数。
Daren Schwenke

5
我不敢相信这被接受为答案。它不是很好。
symcbean

1
关于:缓存-图片,css,htm和js会有所帮助,也请关闭图片上的cookie!
Talvi Watia 2010年

61

我是一个拥有超过1500万用户的网站上的首席开发人员。我们几乎没有扩展问题,因为我们尽早进行了规划并进行了周密的扩展。以下是一些我可以从我的经验中提出的策略。

SCHEMA 首先,对您的模式进行规范化。这意味着,与其拥有多个关系表,不如选择拥有一个大表。通常,联接会浪费宝贵的数据库资源,因为进行多次准备和整理会消耗磁盘I / O。尽量避免使用它们。

这里的权衡是您将要存储/拉冗余数据,但这是可以接受的,因为数据和笼内带宽非常便宜(更大的磁盘),而多个准备I / O则要贵几个数量级(更多的服务器) 。

索引 确保您的查询至少使用一个索引。但是请注意,如果您经常编写或更新索引,则将花费您大量费用。有一些实验技巧可以避免这种情况。

您可以尝试添加其他未索引的列,这些列与被索引的列并行运行。然后,您可以有一个脱机过程,该过程将未索引的列批量写入到已索引的列中。这样,您可以更好地控制mySQL何时需要重新计算索引。

避免像瘟疫这样的计算查询。如果必须计算查询,请尝试在写入时执行一次。

缓存 我强烈推荐Memcached。它已被PHP堆栈(Facebook)上最大的参与者证明,并且非常灵活。有两种方法可以执行此操作,一种是在数据库层中进行缓存,另一种是在业务逻辑层中进行缓存。

DB层选项将需要缓存从DB检索到的查询结果。您可以使用md5()对SQL查询进行哈希处理,并在进入数据库之前将其用作查找关键字。这样做的好处是很容易实现。缺点(取决于实现方式)是您失去了灵活性,因为在缓存过期方面,所有缓存均被视为相同。

在我工作的商店中,我们使用业务层缓存,这意味着系统中的每个具体类都控制自己的缓存架构和缓存超时。这对我们来说效果很好,但是请注意,从数据库中检索到的项目可能与从缓存中检索到的项目不同,因此您必须一起更新缓存和数据库。

数据共享 复制只能使您受益匪浅。超出您的预期,您的写入将成为瓶颈。作为补偿,请确保尽早支持数据分片。如果不愿意,您可能以后想开枪。

实现起来非常简单。基本上,您希望将密钥授权与数据存储区分开。使用全局数据库存储主键和集群ID之间的映射。您查询此映射以获取一个群集,然后查询该群集以获取数据。您可以从该查找操作中缓存地狱,这将使它可以忽略不计。

不利的一面是可能难以将多个分片中的数据组合在一起。但是,您也可以设计解决方案。

离线处理 不必让用户不必等待您的后端。建立一个作业队列并移动您可以脱机的所有处理,使其独立于用户的请求。


9
+1放下手,这应该是公认的答案。有趣的是,我所读过的有关构建数据库的所有内容总是说“尽可能对所有数据进行规范化”,而没有提及进行连接带来的性能损失。我一直凭直觉一直感觉到联接(尤其是多个联接)增加了很多开销,但是直到现在还没有人明确地说过。我希望我能更好地理解您在谈论什么时候MySQL计算索引的控制,这听起来很有趣。
伊万·普赖斯

数据分片对于太大的数据库至关重要。关于实施分片方案,Google(不是搜索引擎的公司)有很多有趣的事情要说。当限制数据库写入次数(和限制表索引重新计算的次数)时,脱机处理也非常重要。我已经看到很多博客(甚至我认为Stack Overflow)也将这种技术用于用户生成的评论/反馈系统。
伊万·普赖斯

1
谢谢你的意见。当VAST执行时间花费在数据I / O或客户机/服务器I / O中时,有人争辩说要对中间层代码进行概要分析是令人惊讶的。与花费1s的数据库查询仅节省5%的成本相比,将40毫秒的PHP进程的执行时间节省20%的ubber复杂优化毫无意义。
thesmart 2011年

42

我曾在一些站点上获得过PHP和MySQL的支持,这些站点每月获得数百万/点击的支持。以下是一些基本知识:

  1. 缓存,缓存,缓存。缓存是减少Web服务器和数据库负载的最简单,最有效的方法之一。缓存页面内容,查询,昂贵的计算,以及任何受I / O约束的内容。Memcache非常简单有效。
  2. 一旦使用完,请使用多台服务器。您可以具有多个Web服务器和多个数据库服务器(带有复制)。
  3. 减少对您的Web服务器的总体请求数。这需要使用expires标头缓存JS,CSS和图像。您还可以将静态内容移动到CDN,这将加快用户的体验。
  4. 衡量和基准。在生产计算机上运行Nagios,并在dev / qa服务器上进行负载测试。您需要知道服务器何时会着火,以便可以防止它。

我建议阅读由Flickr的一位工程师撰写的《构建可扩展的网站》,它是一个很好的参考。

也可以查看我有关可伸缩性的博客文章,其中有很多链接可链接到有关使用多种语言和平台进行扩展的演示文稿:http : //www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1这里有很多很好的信息。最近,我一直在对该主题进行更多的研究,您的回答与我读过的所有内容都一致。Memcache,缓存,用于静态内容的CDN,减少了请求;所有的好东西。我还要在服务器端的静态内容文件(如果在CDN /缓存后面)上生成哈希,以便更新的文件在缓存中具有唯一的签名。另外,可以动态组合静态源文件(css,javascript)(并使用文件名哈希将其缓存)以减少请求。此外,动态生成拇指(并将其存储在缓存中)
Evan Plaice

Google创建了一个名为mod_pagespeed的apache模块,该模块可以处理所有静态内容的所有文件串联,缩小,文件重命名以包括哈希等。最初,它只应为服务器增加一点处理开销,直到缓存(和CDN)中的大部分内容都被填充为止。同样,出于安全性考虑,将可公开访问的(用户)表与表放在同一个数据库中,而不是处理后端(如果出于某种原因,其中一个表被黑客入侵),通常是一个坏主意。
伊万·普赖斯

39

回复:PDO / MySQLi / MySQLND

@ 加里

您不能只说“不要使用MySQLi”,因为它们有不同的目标。PDO几乎就像一个抽象层(尽管实际上不是),其设计目的是使使用多个数据库产品变得容易,而MySQLi特定于MySQL连接。在将PDO与MySQLi进行比较的情况下,不能说PDO是现代访问层,因为您的声明暗示着进展是mysql-> mysqli-> PDO,事实并非如此。

MySQLi和PDO之间的选择很简单-如果您需要支持多种数据库产品,则可以使用PDO。如果您仅使用MySQL,则可以在PDO和MySQLi之间进行选择。

那么,为什么您会选择MySQLi而不是PDO?见下文...

@罗斯

您对MySQLnd是最新的MySQL核心语言级别库是正确的,但是它不能替代MySQLi。MySQLi(与PDO一样)仍然是您通过PHP代码与MySQL交互的方式。两者都使用libmysql作为PHP代码背后的C客户端。问题是libmysql在核心PHP引擎之外,而mysqlnd就是其中的地方,即它是一个本机驱动程序,它利用核心PHP内部结构来最大化效率,特别是在内存使用方面。

MySQLnd由MySQL自己开发,最近已经进入了RC测试的PHP 5.3分支,准备在今年晚些时候发布。然后,您将可以将MySQLnd与MySQLi一起使用,但不能与PDO一起使用。如果您不需要像PDO这样的抽象功能,这将使MySQLi 在许多领域(不是全部)都有性能的提升,并将成为MySQL交互的最佳选择。

就是说,MySQLnd 现在在 PDO的PHP 5.3中可用,因此您可以从ND到PDO获得性能增强的优势,但是,PDO仍然是通用数据库层,因此不太可能从中受益。 MySQLi可以增强ND的功能

尽管这些基准来自2006年,但仍可以在此处找到一些有用的基准。您还需要注意此选项

在确定MySQLi和PDO之间时,需要考虑很多因素。实际上,直到您获得非常高的请求数量才是无关紧要的,在这种情况下,使用为MySQL专为设计的扩展而不是抽象化并提供MySQL驱动程序的扩展才有意义。 。

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


6
我从PDO切换到mysqli,常规查询开始执行的速度快了2倍。
serg

5
@serg:希望发布一些测试来确认这一点,因为我严重怀疑简单地从PDO切换到mysqli会提高速度。
斯坦

23

一般

  • 在开始查看实际负载之前,请勿尝试进行优化。您可能猜对了,但是如果您做不到,那就浪费了时间。
  • 使用jmeterxdebug或其他工具对站点进行基准测试。
  • 如果负载开始成为问题,则可能会涉及对象或数据缓存,因此通常请阅读缓存选项(memcached,MySQL缓存选项)

  • 分析您的代码,以便知道瓶颈在哪里,以及它在代码中还是在数据库中

资料库

  • 如果对其他数据库的可移植性不是很重要,请使用MYSQLi,否则使用PDO
  • 如果基准测试表明数据库存在问题,请在开始缓存之前检查查询。使用EXPLAIN查看查询速度下降的地方。
  • 优化查询并以某种方式缓存数据库后,您可能要使用多个数据库。复制到多个服务器或分片(在多个数据库/服务器上拆分数据)可能是合适的,具体取决于数据,查询和读/写行为的类型。

快取

  • 关于缓存代码,对象和数据,已经完成了大量的编写工作。查找有关APCZend OptimizermemcachedQuickCacheJPCache的文章。在您真正需要执行此操作之前,您将不必担心从未优化开始。
  • APC和Zend Optimizer是操作码缓存,它们通过避免代码的重新解析和重新编译来加快PHP代码的速度。通常安装简单,值得早做。
  • Memcached是通用缓存,可用于缓存查询,PHP函数或对象或整个页面。必须专门编写代码来使用它,如果没有中心点来处理缓存对象的创建,更新和删除,则可能涉及该过程。
  • QuickCache和JPCache是​​文件缓存,否则类似于Memcached。基本概念很简单,但是也需要代码,并且在创建,更新和删除的中心点上更加容易。

  • 考虑使用其他Web服务器以实现高负载。如果您可以牺牲Apache的功能和灵活性(或者如果您只是不需要这些东西,而通常不需要),那么lighthttpnginx这样的服务器可以用比Apache少得多的内存来处理大量流量。
  • 请记住,这些天硬件的价格出奇地便宜,因此,与“让我们购买一台巨型服务器”相比,一定要花费大量精力来优化大量代码。
  • 考虑向此问题添加“ MySQL”和“ scaling”标签

9

APC是绝对必要的。它不仅构成了一个出色的缓存系统,而且从自动缓存的PHP文件中获得的收益真是天赐。至于多数据库的想法,我认为您不会从在同一服务器上拥有不同的数据库中受益匪浅。它可能会在查询期间使您的速度有所提高,但是我怀疑为确保这三个代码同步而部署和维护这三个代码所付出的努力是否值得。

我也强烈建议运行Xdebug来查找程序中的瓶颈。优化使我轻而易举。


9

首先,正如我认为Knuth所说的那样,“过早的优化是万恶之源”。如果您现在不必处理这些问题,那么就不必着重于首先提供可以正常运行的功能。话虽如此,如果优化迫不及待。

尝试对数据库查询进行性能分析,找出运行缓慢的情况以及发生的情况,然后从中提出优化策略。

我将研究Memcached,因为它是许多高负载站点用于有效地缓存所有类型的内容的工具,并且与它的PHP对象接口非常好。

在服务器之间分配数据库并使用某种负载平衡技术(例如,在1到#个冗余数据库之间随机生成一个具有必要数据的数字-并使用该数字来确定要连接到哪个数据库服务器)也是增加存储空间的绝佳方法效率。

过去,在某些负载较高的站点上,所有这些都工作得很好。希望这有助于您入门:-)


1
RequiredFullQuote:“我们应该忘记效率低下的问题,大约有97%的时间是这样:过早的优化是万恶之源”
Alister Bulman

RequiredReallyFullQuote:“程序员浪费大量时间来考虑或担心程序非关键部分的速度,而这种效率的尝试实际上在考虑调试和维护时会产生严重的负面影响。我们应该忘记效率低下,大约有97%的人说:过早的优化是万恶之源,但我们不应该在这3%的临界水平上放弃机会。
cHao

6

使用Xdebug(建议使用tj9991)对应用程序进行性能分析绝对是必须的。盲目地优化事物并没有多大意义。Xdebug将帮助您找到代码中的真正瓶颈,因此您可以明智地花费优化时间并修复实际上导致速度降低的代码块。

如果您使用的是Apache,那么Siege是另一个可以帮助测试的实用程序。通过真正调整速度,它将帮助您预期服务器和应用程序将如何应对高负载。

用于PHP的任何类型的操作码缓存(例如APC或许多其他之一)也将有很大帮助。


6

我经营的网站每月有7-8百万的页面浏览量。并不是很多,但足以使我们的服务器感到负担。我们选择的解决方案很简单:数据库级别的内存缓存。如果数据库负载是您的主要问题,则此解决方案效果很好。

我们开始使用Memcache来缓存整个对象和最常用的数据库结果。它确实起作用,但是它也引入了错误(如果我们更加小心的话,我们可能会避免其中的一些错误)。

因此,我们改变了方法。我们构建了一个数据库包装器(使用与旧数据库完全相同的方法,因此很容易切换),然后将其子类化以提供内存缓存数据库访问方法。

现在,您要做的就是确定查询是否可以使用缓存的(可能已过期)结果。用户直接运行的大多数查询现在都直接从Memcache中获取。更新和插入是例外,主要网站的更新和插入仅由于日志记录而发生。这个相当简单的措施将我们的服务器负载减少了约80%。


6

值得一提的是,即使没有像memcached这样的扩展程序/帮助程序包,缓存也是PHP中的DIRT SIMPLE。

您需要做的就是使用创建一个输出缓冲区ob_start()

创建一个全局缓存功能。调用ob_start,将函数作为回调传递。在函数中,查找页面的缓存版本。如果存在,则服务并结束。

如果不存在,脚本将继续处理。当到达匹配的ob_end()时,它将调用您指定的函数。那时,您仅获得输出缓冲区的内容,将它们放入文件中,保存文件,然后结束。

添加一些到期/垃圾回收。

许多人没有意识到您可以嵌套ob_start()/ ob_end()调用。因此,如果您已经在使用输出缓冲区来解析广告或进行语法突出显示等操作,则可以嵌套另一个ob_start/ob_end调用。


+1,因为它看起来很有趣。我不知道它在性能方面的表现如何
Sylverdrag

+1,因为这是一个有趣的想法。这些回调可以为我调用我的缓存类!
Xeoncross

5

感谢您对PHP缓存扩展的建议-您能解释一下一个使用另一个的原因吗?我听说过有关通过IRC进行内存缓存的很棒的事情,但从未听说过APC-您对此有何看法?我认为使用多个缓存系统会产生很大的反作用。

实际上,许多人确实一起使用APC和memcached ...


4

看来我错了。MySQLi仍在开发中。但是根据这篇文章,PDO_MySQL现在由MySQL团队提供。从文章:

MySQL改进的扩展名mysqli是旗舰。它支持MySQL服务器的所有功能,包括字符集,预准备语句和存储过程。该驱动程序提供了一个混合API:您可以根据自己的喜好使用过程或面向对象的编程风格。mysqli附带PHP 5及更高版本。请注意,PHP 4的生命周期终止于2008-08-08。

PHP数据对象(PDO)是数据库访问抽象层。PDO允许您对各种数据库使用相同的API调用。PDO不提供任何程度的SQL抽象。PDO_MYSQL是PDO的MySQL驱动程序。PDO_MYSQL与PHP 5一起提供。自PHP 5.3起,MySQL开发人员积极地为它做贡献。统一API的PDO好处是以不通过统一API完全支持MySQL特定功能(例如多个语句)为代价的。

请停止使用发布的第一个MySQL PHP驱动程序:ext / mysql。自从2004年使用PHP 5引入MySQL改进的扩展程序mysqli以来,没有理由仍然使用最旧的驱动程序。ext / mysql不支持字符集,预备语句和存储过程。它仅限于MySQL 4.0的功能集。请注意,对MySQL 4.0的扩展支持在2008-12-31截止。不要将自己局限于这些旧软件的功能!升级到mysqli,另请参见Converting_to_MySQLi。从我们的角度来看,mysql处于仅维护模式。

对我来说,这篇文章似乎偏向MySQLi。我想我对PDO有偏见。我真的很喜欢MySQLi上的PDO。对我来说直截了当。该API与我编写的其他语言非常接近。OO数据库接口似乎更好地工作。

我还没有遇到过PDO无法提供的任何特定MySQL功能。如果我这样做,我会感到惊讶。


3

PDO也非常慢,其API也非常复杂。如果不考虑可移植性,则没有人理智地使用它。让我们面对现实吧,在所有Web应用程序的99%中,事实并非如此。您只需要坚持使用MySQL或PostrgreSQL或其他正在使用的工具。

至于PHP问题以及要考虑什么。我认为过早的优化是万恶之源。;)首先完成您的应用程序,在进行编程时尝试使其保持干净,编写一些文档并编写单元测试。有了以上所有内容,您就可以在任何时候重构代码。但是首先,您需要完成并推出它,以了解人们对此有何反应。


2

当然PDO是好的,但也 一些关于它的性能与mysql和mysqli的争议,虽然它似乎已经得到解决。

如果您设想可移植性,则应使用pdo,但如果没有,则应该使用mysqli。它具有OO接口,准备好的语句以及pdo提供的大多数功能(当然,可移植性除外)。

另外,如果确实需要性能,请为PHP 5.3中的(本地mysql)MysqLnd驱动程序做准备,该驱动程序将与php紧密集成,从而具有更好的性能和改进的内存使用率(以及用于性能调整的统计信息)。

如果您具有群集服务器(和类似YouTube的负载),则Memcache很好,但我也将首先尝试APC


2

已经给出了很多好的答案,但是我想向您指出一个名为XCache的备用操作码缓存。它是由一个轻量级的贡献者创建的。

另外,如果将来可能需要对数据库服务器进行负载平衡,则MySQL Proxy可以很好地帮助您实现这一目标。

这两个工具都应该很容易地插入到现有应用程序中,因此可以在需要时进行此优化,而不会造成太多麻烦。


2

第一个问题是您真正希望它有多大?您计划在基础架构上进行多少投资。由于您觉得有必要在这里提出问题,因此我猜您希望在有限的预算范围内从小做起。

如果该站点不可用,则性能无关紧要。为了获得可用性,您需要水平扩展。您可以明智地摆脱的最低限度是2台服务器,都运行apache,php和mysql。将一个DBMS设置为另一个DBMS的从属。在master上进行所有写操作,并在本地数据库上进行所有读操作(无论是什么操作)-除非出于某些原因需要回读刚读取的数据(使用master)。确保您已具备适当的设备来自动提升从属并隔离主控。对Web服务器地址使用轮询DNS,以为从节点提供更多亲和力。

在此阶段将数据跨不同数据库节点进行分区是一个非常糟糕的主意-但是,您可能要考虑在同一服务器上的不同数据库之间进行拆分(这将在您超过facebook时促进跨节点的分区)。

请确保您已使用监视和数据分析工具来衡量站点性能并确定瓶颈。可以通过编写更好的SQL /修复数据库架构来解决大多数性能问题。

将模板缓存保留在数据库上是一个愚蠢的想法-数据库应该是结构化数据的中央通用存储库。将模板缓存保留在Web服务器的本地文件系统上-它将更快地可用,并且不会减慢数据库访问的速度。

不要使用操作码缓存。

花大量时间研究您的网站及其日志,以了解其运行如此缓慢的原因。

将尽可能多的缓存推送到客户端。

使用mod_gzip压缩所有内容。

C。


2

我的第一条建议是考虑这个问题并在设计网站时牢记在心,但是不要过分。通常很难预测一个新站点的成功,我会花更多的时间尽早完成并在以后对其进行优化,这将是更好的选择。

通常,简单是快速的。模板会使您减速。数据库会使您减速。复杂的库会使您慢下来。将模板彼此分层,从数据库中检索模板并将其解析到复杂的库中->时间延迟彼此成倍增加。

基本站点启动并运行后,请进行测试,以向您展示您在其中花费的精力。很难找到目标。通常,为了加快处理速度,您将不得不解开代码的复杂性,这使其变得更大且更难维护,因此您只想在必要时这样做。

以我的经验,建立数据库连接是相对昂贵的。如果可以解决,请不要在访问量最大的页面(如网站首页)上连接一般访问者的数据库。创建多个数据库连接简直是疯狂,几乎没有好处。


1

@ 加里

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

我现在很喜欢PDO,看来您是对的-但是我知道MySQL正在为PHP开发MySQLd扩展-我想成功取代MySQL或MySQLi-您对此有何看法?


@ 瑞安埃里克tj9991

感谢您对PHP缓存扩展的建议-您能解释一下一个使用另一个的原因吗?我听说过有关通过IRC进行内存缓存的很棒的事情,但从未听说过APC-您对此有何看法?我认为使用多个缓存系统会产生很大的反作用。

我一定会整理出一些性能测试器-非常感谢您对这些测试器的建议。


1

我没有看到自己很快会从MySQL切换-因此我想我不需要PDO的抽象功能。感谢DavidM的那些文章,他们对我有很大帮助。



1

我不敢相信没有人提到过:模块化和抽象。如果您认为您的站点将不得不增长到很多机器,则必须对其进行设计,以便可以!这意味着诸如不要假设数据库位于本地主机上这样的愚蠢事情。这也意味着一开始会很麻烦的事情,例如编写数据库抽象层(例如PDO,但要轻得多,因为它只完成您需要做的事情)。

这意味着要使用框架。您将需要对代码进行分层,以便稍后可以通过重构数据抽象层来提高性能,例如,通过教导它一些对象位于不同的数据库中而不必知道或关心代码

最后,请注意占用大量内存的操作,例如不必要的字符串复制。如果您可以降低PHP的内存使用量,则可以从Web服务器中获得更高的性能,这在使用负载平衡解决方案时会有所扩展。


1

如果您正在处理大量数据,并且缓存没有减少数据,请查看Sphinx。使用SphinxSearch不仅可以实现更好的文本搜索,而且在处理较大的表时可以作为MySQL的数据检索替代品,因此我们取得了丰硕的成果。如果您使用SphinxSE(MySQL插件),它会超过我们多次缓存后获得的性能提升,并且应用程序实现是小菜一碟。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.