Рефакторинг Wordpress для улучшения производительности памяти [закрыто]

63

Я внимательно посмотрел на потребление памяти Wordpress. На моем сайте кажется, что для каждой страницы выделяется 20 МБ ОЗУ, просто для того, чтобы подготовить удобную среду для запуска всех плагинов. Я построил это так:

Нет ни единого места для оптимизации, ни одного плохого парня, который съел бы большую часть памяти. Потребление распространяется на многие многие многие модули PHP.

Как мы можем заставить Wordpress инициализировать свое окружение в памяти только один раз, а затем многократно использовать его для каждого удара? Я не хочу, чтобы медленный PHP потреблял 20 МБ при каждом клике пользователя - даже на сервере с большим объемом памяти для выполнения всей этой работы требуются секунды. В основном вам понадобятся блоки памяти, доступные только для чтения, которые можно использовать повторно.

Кроме того ... почему 20 МБ? Кто-нибудь может дать представление об этом?

Редактировать: Вот вывод WinCacheGrind на Wordpress, работающий на моей машине разработки (значительно быстрее, чем общий хостинг). Как видите, на создание HTML-кода главной страницы уходит более секунды. Замедлите это на общем хостинге, и у вас есть рецепт для неприятностей. Я выбрал метод, который занимает большую часть времени. Как бы вы пошли на оптимизацию этого?

Изменить: Вот статистика запросов из этого фантастического инструмента профилирования functions.php .

Загрузка: 12 запросов - 532 мс - 19,1 МБ - 43 попадания в кэш / 53
Запрос: 15 запросов - 563 мс - 19,0 МБ - 72 попадания в кеш / 86
Отображение: 21 запрос - 705 мс - 19,2 МБ - 234 попадания в кэш / 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 быстрее, но и кушает больше памяти.

Вот список по включаемому файлу.

Это позволило мне понять, сколько памяти потребляется «Все в одном SEO-пакете» - одним способом было бы использовать только часть функциональности плагина, чтобы получить то, что я хочу. Кроме того, мои собственные плагины кажутся довольно плохими.

Я хотел бы попробовать условную загрузку, например, на comment.php (я запрещаю комментарии в моем блоге) и некоторых других. Я удалил весь устаревший код. Я урезал kses.php, чтобы загружать только его глобальные таблицы по требованию. Я упростил l10n (я не делаю локализацию), заставляя его функции возвращать строки сразу, без поиска. Я все еще далек от 30-процентной отметки, которую я произвольно установил.

Изменить: Я загрузил и включил APC с настройками по умолчанию (32 МБ кэш-кода операции). Вот сравнение:

Вы можете видеть, что загрузка кода значительно ускорилась, и код также занимает меньше места в памяти (вероятно, потому что мы имеем дело только с кодами операций, а не с исходным кодом). Потребление памяти, однако, все еще довольно высоко.

Роман Зенка
источник
Не могли бы вы загрузить куда-нибудь сам файл cachegrind? Просто заметьте, я не помню, есть ли что-то, что стоит держать в секрете, если оно есть - тогда не делайте.
Первый
@Rarst Это должно быть хорошо. foxloft.com/files/mbala/cachegrind.out
Роман Зенка,
1
хм, я согласен с вашим выводом - ничего толком не выскакивает, прося починить. Я сбросил новый профиль в свой локальный набор тестов (3.1, MS, Twenty Ten, Theme Unit Test) и получил 1,5 секунды (большая разница, кажется, из-за пользовательского меню - дело в slooow). Так что, думаю, ничего не исправить = кеширование исследований.
Rarst
@Rarst Большое спасибо за вашу помощь. Я действительно думаю, что есть вещи, которые нужно исправить, но для этого потребуется изменить архитектуру Wordpress на совершенно иную философию, а это слишком много работы.
Роман Зенька

Ответы:

25

Не стоит хлопот. WordPress не ест много памяти только потому, что. Он ест много памяти, потому что он работает много функций под капотом.

Гораздо проще и эффективнее кешировать результаты (сгенерированные страницы) с помощью статического плагина кеша и обслуживать его. Таким образом, большинство посетителей даже не попадут в сам WP.

Rarst
источник
2
Я уже использую кеш, но у меня все еще есть несколько страниц, которые действительно динамичны по своей природе (например, корзина для покупок). И когда звезды не выровнены правильно, пользователь может подождать 20 секунд - то есть, на GoDaddy, но даже если нет, я думаю, что это будет, по крайней мере, ~ 3 секунды. Я просто не могу представить, как люди привыкли к Google.
Роман Зенька
8
@Roman Zenka, если у вас есть конкретные требования к производительности, вам лучше искать конкретные решения, чем надеяться, что сам WordPress волшебным образом станет очень быстрым и потребляет мало ресурсов. Первое, на что я бы посоветовал взглянуть, - это кэш кода операции и статическое кеширование фрагмента ... Но перед этим вам нужно сравнить его и определить не только куда идет память, но и где тратится время. WordPress - это среда, а не узкое место. Узкое место в том, что вы заставляете это делать.
Rarst
@ Во-первых, я действительно проверил использование процессора и не могу указать пальцем на какое-то конкретное место, которое вызывает проблему. Похоже на память - кажется, что она распространена повсюду. Тем не менее, мой сравнительный анализ может быть выполнен не оптимальным способом - я использую профилировщик XDebug и Cachegrind - например, довольно трудно разделить задержку из-за вызовов базы данных. Я был бы благодарен за указатели на лучшие методы профилирования.
Роман Зенка
Добавлен скриншот @Rarst Profiling.
Роман Зенка
4
Возможно, серверы GoDaddy работают медленно. Они известны тем, что у них нет лучшего оборудования, и « скорее заплатят за телевизионную рекламу, чем обновят свои серверы »
Зак
23

И именно поэтому я думаю, что WordPress серьезно нуждается в переписывании. Вы больше не можете винить потребление памяти за сложность того, что он делает. Он просто делает что-то не так.

Какой наивный вывод. Читай то, что никогда не делай, Часть первая .

Спасибо за графики использования памяти, хотя.

Гораздо позже редактирование: Autommatic выпустил библиотеку prefork, которая, кажется, делает то, что вы просите: загружать код WordPress в ОЗУ только один раз.

scribu
источник
Правда, это наивно. Может быть, я должен был сказать «рефакторинг» вместо «переписать», тогда это звучит намного лучше. Сообщение обновлено.
Роман Зенька
2
Хорошо, хорошо, если у вас есть конкретные предложения (особенно исправления), вы можете опубликовать их на trac: core.trac.wordpress.org
scribu
Я работаю над этим прямо сейчас. Я пытаюсь построить карту объектов в памяти, чтобы я мог видеть, сколько используется чем. Есть ли инструмент, который бы взял дамп памяти и построил его?
Роман Зенька
5
@scribu - +1 за ссылку на пост Джоэла!
MikeSchinkel
1
Хорошо, имейте в виду, что WP_Object_Cache можно заменить реализацией memcached и т. Д.
scribu
17

Начиная с WordPress 3.2, PHP 5.2 будет минимальным требованием. Я думаю, с этим под нашими поясами, кусочки ядра могут начать реструктурироваться и использовать классы с автозагрузкой. Это позволило бы нам избежать загрузки некоторых фрагментов кода, если они действительно не нужны. Например, если в просмотре страницы не было вставок или галерей, мы могли бы избежать загрузки большого количества медиакода.

Тем не менее, даже если они решат пойти по этому пути, я ожидаю, что это будет медленная эволюция (как и большинство других происходящих изменений под капотом). Это потребует перестановки вокруг множества файлов и кода, что может привести к нарушению обратного компиляции для некоторых плагинов.

Частично проблема (если это действительно можно так назвать) заключается в том, что без такой условной загрузки базовая структура не может заранее знать, какая функциональность ему понадобится или не понадобится для генерации представления контента. Поэтому многие функции должны быть загружены на тот случай, если они понадобятся.

Дугал Кэмпбелл
источник
@Dougal Campbell Я начал щедрость по этому вопросу, чтобы посмотреть, сможем ли мы взломать хотя бы один этот экземпляр WordPress достаточно плохо, чтобы улучшить потребление памяти как минимум на 30% сейчас, относительно безболезненно. Это может вдохновить на дальнейшее развитие.
Роман Зенька
Условная загрузка, потенциально снижая потребление памяти, снижает скорость, когда задействовано кэширование кода операции . Мы склонны отдавать предпочтение скорости.
scribu
Больше мыслей по
поводу
@scribu Когда вы говорите «условная загрузка», вы говорите об автозагрузке или о фактической загрузке кода на основе условия? Насколько это вредит скорости?
Роман Зенка,
1
Спасибо! Как я уже сказал, я не знаю, пойдет ли когда-нибудь ядро ​​WP по этому пути (требуемый рефакторинг может быть слишком экстремальным). Но я был очень впечатлен усилиями, которые вы приложили для анализа этого, и графиками, которые вы создали. Продолжайте хорошую работу!
Дугал Кэмпбелл
16

Как мы можем заставить Wordpress инициализировать свое окружение в памяти только один раз, а затем многократно использовать его для каждого удара?

Это называется кешированием кода операции.

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

эфирное масло
источник
1
Я собираюсь дать APC попробовать и посмотреть, что произойдет. Когда я первоначально задавал этот вопрос, я имел в виду нечто большее, чем просто кэширование кода операции - я имел в виду повторное использование всей среды, которую создает WordPress - код + данные. Memcached поможет вам быстрее получать данные, но вы все равно будете клонировать данные в памяти сервера. Теперь кажется, что кеширование кода операции может позаботиться о ~ 90% всего потребления памяти.
Роман Зенка
Если у вас есть ресурсы для некоторых экспериментов, вы также можете попробовать настроить среду FastCGI. Я был бы очень заинтересован в некоторых сравнениях между mod_php и работой под FastCGI.
Дугал Кэмпбелл
5

вам, вероятно, не удастся так сильно сократить использование оперативной памяти. Но если вы используете mod_php, вы можете mod_fcgidвместо этого переключиться на .

хотя mod_php немного медленнее, он загружает php даже тогда, когда в этом нет необходимости, например, для обслуживания изображений, статических файлов или даже кэширования. Если у вас много запросов, это много оперативной памяти.

использование fcgid значительно уменьшит это.

Кроме того , с помощью статического кэша (как w3total кэш) будет избегать вызова PHP вообще , который является действительно большим преимуществом: использовать меньше оперативной памяти, меньше соединений дБ.

boyska
источник
4

Ха. Сейчас я работаю над веб-приложением, которое я полностью намереваюсь перегружать данными и использованием сверх того, что может обрабатывать моя учетная запись общего хостинга, поэтому я решил - хотя это было бы очень легко встроить в WP - попробовать работать из BackPress как каркас и построить только то, что мне нужно для моих конкретных случаев использования.

Таким образом, я смог сократить свою базовую среду с сотен PHP-файлов в WP до примерно двадцати или около того, что мне действительно нужно, и в то же время я могу использовать все возможности db, HTTP, управления пользователями, форматирования и cron. функции, которые я люблю в WordPress.

Проблема в том, что это большая работа, и я бы никогда не стал доверять моему хакджобу ни за что, кроме моего личного использования. Если вы хотите использовать полную среду WP, принимайте ее как есть. Это так же хорошо, как и благодаря сотням разработчиков, которые настраивали его в течение нескольких лет. Как все здесь говорили, вы получите гораздо больше, найдя лучший план хостинга и исследуя методы кэширования, чем вы, вероятно, взломав ядро.

goldenapples
источник
1
Я согласен, что WP был настроен в течение длительного времени. Но я не думаю, что он был настроен для работы на дрянном хостинге с определенной смесью плагинов. Мне любопытно посмотреть, как далеко я могу продвинуть это. Даже если изменения не внесены в ядро, хорошо иметь документированный способ взлома ядра, если вы считаете, что должны это сделать.
Роман Зенка
3

Да, WordPress сначала загружает все, а затем делает то, что мы просим. Я могу вспомнить где-нибудь, что мы можем создать виртуальный пул в ОЗУ, куда мы можем помещать файлы. У меня была идея поместить весь WordPress в память (<10 МБ), и тогда мы сможем сэкономить много операций ввода-вывода, что само по себе должно повысить скорость. Но у меня никогда не было возможности попробовать это, и к тому же я не настолько опытен в достижении чего-то подобного. Но, похоже, стоит попробовать.

Ashfame
источник
И я согласен с Rarst использовать плагин статического кеша, чтобы обработка вообще не выполнялась. Но это можно использовать и с хорошей динамикой. :)
Ashfame
Мне нравится эта идея. Я не уверен, какая часть этой проблемы связана с задержками ввода-вывода, а какая из-за того, что PHP медленно пережевывает данные. Вы знаете, как сказать?
Роман Зенка,
Извините, это просто идея в моей голове. Может быть, это не влияет на производительность так сильно, как может показаться, поскольку данные обычно считываются с жесткого диска в виде блоков, поэтому многие другие требуемые данные уже могут быть получены. Я не слишком уверен.
Ashfame
3

несколько основных предложений:

  1. w3 всего кеша плагин для кеширования ..
  2. установите и включите memcache, а также включите общие настройки кэша w3 (кэш кода операции также хорош, но не подходит для плагина общего кэша w3)
  3. минимизировать запросы на прямые ссылки в файлах темы.
  4. Отключите все дополнительные неиспользуемые плагины и удалите.
  5. оптимизировать базу данных.

Я работаю на известном WordPress сайте с огромным трафиком ежедневно. Я не на преданном даже, отлично справляюсь для меня :)

Аяз Малик
источник