我仔细研究了Wordpress的内存消耗。在我的网站上,似乎为每个页面命中分配了20MB的RAM,只是为了为所有要运行的插件准备一个舒适的环境。因此,我对它进行了绘制:



没有一个地方可以优化,没有一个坏家伙会消耗大部分的内存。消费分布在许多许多php模块中。

我们如何才能使Wordpress仅在内存中初始化其环境一次,然后为每次命中多次重复使用它?我不想让缓慢的PHP在每次用户单击时都占用20 MB的空间-即使在具有大量内存的服务器上,也要花费数秒钟才能完成所有工作。您基本上将需要只读的内存块,这些内存可以重复使用。

...为什么20MB?任何人都可以提供对此的见解吗?

编辑:这是在我的开发计算机上运行的Wordpress上的WinCacheGrind输出(比共享主机快得多)。如您所见,仅花费一秒钟的时间就可以生成主页的HTML。通过共享主机降低速度,您会遇到麻烦。我选择了大部分时间使用的方法。您将如何优化它?



编辑:这是此出色的functions.php分析工具的查询统计信息。

Load: 12 queries - 532ms - 19.1MB - 43 cache hits / 53
Query: 15 queries - 563ms - 19.0MB - 72 cache hits / 86
Display: 21 queries - 705ms - 19.2MB - 234 cache hits / 257


编辑:您是否想看到一定会吓到您的东西?将这些行插入index.php的末尾:


echo "<pre>\n";
print_r(get_defined_vars());
echo "</pre>\n";


我试图计算当前帖子的正文存储在内存中的次数。我计算了20个实例。然后我意识到PHP具有引用计数,因此副本的数量减少到只有三个:两个似乎在WP_Query中,一个在对象缓存中。我正在进一步调查。

这就是为什么我认为WordPress需要针对内存问题进行重构的原因。您再也不能将其内存消耗归咎于其功能的复杂性。简直就是一堆错。

编辑:经过一天的努力,这是我的发现:

1)88%的内存来自来自require或include或include_once类型的调用:



2)php文件包含的大部分时间是在处理请求的第一部分(并不奇怪),这是在所有内存都被消耗掉的地方:



3)绘制发出请求期间正在执行的所有功能非常有趣。共有12000多个电话。我将它们抖动以使其更加可见(“水平”轴基本上是堆栈的深度):



4)我能想到的唯一方法是将包括的.php文件数量。如果我将每个文件的功能分开,则可以看到许多文件最多被命中一次或两次。我们需要一种方法来在不需要它们时跳过它们。例如,我的远程数据库备份插件已加载并注册,根本就从未使用过。这是上面按文件名划分的图:



我提供了值得我所有声誉的赏金:)重构,可以减少我的博客内存占用30%或更多。

编辑:我安装了WP 3.1,这是与旧版本的比较。



蓝色是WP 3.1,红色为3.0.4。新的WP更快,​​但也占用更多内存。

这是包含文件的列表。



这让我意识到“ All In One SEO包”消耗了多少内存-一种途径是仅使用插件功能的一小部分来获取我想要的东西。另外,我自己的插件似乎还不错。

我想尝试例如条件加载comment.php(我不允许在博客上发表评论)和其他几个。我删除了所有不推荐使用的代码。我整理了kses.php以仅按需加载其全局表。我简化了l10n(我不进行本地化),使它的函数立即返回字符串,而无需查找。我仍未达到我随意设置的30%标记。

编辑:我下载并启用了APC的默认设置(操作码缓存为32MB)。比较如下:



您可以看到代码加载速度大大加快,并且代码占用的内存也更少(可能是因为我们只处理操作码,不是原始来源)。但是,内存消耗仍然很高。

评论

您可以将cachegrind文件本身上传到某个地方吗?请注意,我不记得其中是否包含任何值得保密的内容,如果有的话-那就不要。

@Rarst应该没问题。 foxloft.com/files/mbala/cachegrind.out

嗯,我同意您的结论-真的没有任何事情跳出来,要求解决。我已经将新的配置文件转储到了本地测试堆栈(3.1,MS,二十,主题单元测试数据)中,并得到了1.5s(大部分差异似乎是由于自定义菜单-事情太糟糕了)。因此,我想没有什么可以修复=缓存研究。

@Rarst非常感谢您的帮助。我确实认为需要解决一些问题,但这需要将Wordpress的体系结构更改为完全不同的哲学,这是太多的工作。

#1 楼

不值得的麻烦。 WordPress不会因为它而占用很多内存。它消耗大量内存,因为它在后台运行了许多功能。

使用静态缓存插件缓存结果(生成的页面)并为其提供服务要容易得多,效率更高。这样大多数访问者甚至都不会点击WP本身。

评论


我已经在使用缓存,但是仍然有一些页面实际上是动态的(例如购物车)。而且,当星星没有正确分配时,用户可以等待20秒-即在GoDaddy上允许,但即使没有,我认为至少也要3秒左右。我简直无法提供人们习惯于Google的那种真正敏捷的体验。

–罗马Zenka
2011-2-26 14:50

@Roman Zenka,如果您有特定的性能需求,那么您最好是寻找特定的解决方案,而不是希望WordPress本身会变得神奇而快速,并节省资源。我建议看的第一件事是操作码缓存和片段静态缓存...但是在此之前,您需要先对其进行基准测试,不仅要确定内存的去向,还要确定花在哪里。 WordPress是环境,而不是瓶颈。瓶颈在于您的工作方式。

–稀有
2011-2-26 15:20

@Rarst我实际上已经对CPU使用情况进行了基准测试,并且我不能将手指放在任何引起问题的特定位置。与记忆类似-它似乎遍布各处。但是,我的基准测试可能不是以最佳方式完成的-我使用了XDebug分析器和Cachegrind-例如,由于数据库调用的原因,很难很好地区分延迟。我希望能找到更好的分析技术的指针。

–罗马Zenka
2011-2-26在16:45



添加了@Rarst Profiling屏幕截图。

–罗马Zenka
2011-2-26在16:54

也可能是GoDaddy的服务器运行缓慢。他们以没有最好的硬件而著称,并且“宁愿为电视广告付费而不是升级服务器”

–扎克
2011年3月1日在20:04

#2 楼


这就是为什么我认为WordPress非常需要重写的原因。您可以
不再将其内存消耗归咎于其工作的复杂性。
它只是在做错事。


天真的结论。读了你永远都不要做的事情,第一部分。

但是,感谢内存使用情况图。

后来编辑:Autommatic发布了一个名为prefork的库您要的是:将WordPress代码仅在RAM中加载一次。

评论


是的,这很幼稚。也许我应该说“重构”而不是“重写”,那么听起来要好得多。发布更新。

–罗马Zenka
2011-2-27在15:29



好的,如果您有具体建议(特别是补丁),欢迎将其发布在trac上:core.trac.wordpress.org

–抄写员
2011-2-27在15:33



我正在处理它。我正在尝试在内存中绘制对象图,所以我可以看到使用了多少对象。有没有一种工具可以进行内存转储并将其绘制出来?

–罗马Zenka
2011-2-27在15:35

@scribu-+1链接到Joel的帖子!

– MikeSchinkel
2011-2-27在17:55

好的,请记住,可以将WP_Object_Cache替换为memcached实现等。

–抄写员
2011-2-27在19:58

#3 楼

从WordPress 3.2开始,最低要求是PHP 5.2。我认为,随着我们的努力,核心的某些部分可以开始进行重组,并使用具有自动加载功能的类。这将使我们避免加载某些代码块,除非实际需要它们。例如,如果页面视图中没有嵌入或画廊,我们也许可以避免加载很多媒体代码。

但是,即使他们决定走那条路,我也会期望它是一个缓慢的演变过程(就像已经发生的许多其他幕后变革一样)。这将需要对许多文件和代码的位置进行改组,这可能会破坏某些插件的向后兼容。

问题的一部分(如果可以真正称之为)这种条件加载,核心框架无法提前知道生成内容视图所需的功能。因此,为了以防万一,必须加载许多功能。

评论


@Dougal Campbell我开始悬赏这个问题,以查看我们是否可以破解至少一个这样的WordPress实例,其性能足以使现在至少至少30%的内存消耗改进,相对轻松。它可以激发未来的发展。

–罗马Zenka
2011-2-27在23:22

条件加载虽然有可能减少内存消耗,但在涉及操作码缓存时会损害速度。我们倾向于速度。

–抄写员
2011-2-27在23:22

有关自动加载的更多想法:stackoverflow.com/questions/4788452/…

–抄写员
2011-2-27在23:29

@scribu当您说“有条件的加载”时,您是在谈论自动加载,还是实际上是根据条件加载代码?它对速度有多大的伤害?

–罗马Zenka
2011-2-28在17:26

谢谢!如我所说,我不知道WP核心是否会采用这种方式(所需的重构可能太极端了)。但是您为分析此问题所付出的努力以及所产生的图表给我留下了深刻的印象。保持良好的工作!

–道格拉斯·坎贝尔
2011-3-7 13:41

#4 楼


如何才能使Wordpress初始化其环境在内存中一次,
然后每次重击多次



这称为操作码缓存。

http://en.wikipedia.org/wiki/PHP_accelerator

评论


我将尝试APC,看看会发生什么。当我最初问这个问题时,我的意思不仅仅是操作码缓存-我的意思是重用WordPress构建的整个环境-代码+数据。 Memcached可以帮助您更快地获取数据,但是您仍将克隆服务器内存中的数据。现在看来,操作码缓存将潜在地解决所有内存消耗的90%。

–罗马Zenka
2011-2-28在0:58



如果您有足够的资源来进行一些实验,则也可以尝试设置FastCGI环境。我对mod_php与在FastCGI下运行之间的一些比较非常感兴趣。

–道格拉斯·坎贝尔
2011-02-28 14:01

#5 楼

您可能无法设法减少ram的使用量。
但是如果您使用mod_php,则可能要改用mod_fcgid

mod_php稍微慢一点,它会加载php,即使不需要,例如提供图片,静态文件,甚至是缓存。如果您有很多请求,那么内存就很多。

使用fcgid可以减少很多。

此外,使用静态缓存(如w3total缓存)也可以避免完全调用php确实是一个很大的优势:更少的ram使用率,更少的数据库连接。

#6 楼

哈。现在,我正在开发一个Web应用程序,我完全打算超载我的共享托管帐户无法处理的数据和使用量,因此,我决定-尽管在WP中构建起来非常容易-但还是可以尝试使用BackPress一个框架,并仅构建我特定用例所需的内容。

因此,我能够将核心环境从WP中的数百个PHP文件减少到实际需要的二十个左右,同时仍然能够利用所有的db,HTTP,我在WordPress中喜欢的用户管理,格式和cron函数。

问题在于它需要大量工作,并且我永远不会相信hackjob可以用于我个人用途之外的任何事情。如果要使用完整的WP环境,请按原样使用。它之所以如此出色,是因为数以百计的开发人员在几年内对其进行了微调。就像这里的每个人都说过的那样,您将找到一个更好的托管计划并研究缓存技术,这比黑客入侵内核可能会走得更远。

评论


我同意WP已经微调了很长时间。但是,我认为使用特定的插件组合来进行糟糕的托管工作并不是微调的。我很好奇我能推多远。即使更改没有进入内核,如果您认为必须的话,最好还是有文件记载的方法入侵内核。

–罗马Zenka
2011-3-3在2:46

#7 楼

是的,WordPress首先加载所有内容,然后执行我们要求的操作。我回想起某个地方,我们可以在RAM中创建一个虚拟池,在其中放置文件。
我有一个想法,就是将整个WordPress放在内存中(<10MB),然后我们可以节省很多I / O仅此一项即可提速。但是我从来没有机会尝试过它,而且我并不真正精通这种东西。但是看起来值得一试。

评论


而且我同意Rarst使用静态缓存插件,以便完全不进行任何处理。但这也可以用于良好的动态。 :)

–嘘声
2011-2-25在19:36

我喜欢这个主意。我不确定这个问题有多少是由于I / O延迟引起的,有多少是由于PHP缓慢地咀嚼数据引起的。您知道如何辨别吗?

–罗马Zenka
2011-02-26 14:52

对不起,这只是我的主意。可能对性能没有太大影响,因为通常从硬盘作为块读取数据,因此可能已经获取了许多其他数据。我不太确定。

–嘘声
2011年3月6日在9:51

#8 楼

一些基本建议:
用于缓存的w3总缓存插件..
安装并启用memcache,也可以从w3总缓存设置启用(操作码缓存也是一个不错的选择但不适用于w3总缓存插件)
最小化查询以直接链接主题文件。
禁用所有多余的未使用插件并删除。
优化数据库。

我正在运行一个知名的wordpress网站,该网站每天都有大量流量。.我什至没有专心致志,对我有好处:)