Ars Longa, Vita Brevis

Увеличиваем производительность WordPress подручными методами

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

Тем не менее, это заставило меня задуматься о том, как WordPress использует собственный кэш и что можно сделать, чтобы улучшить производительность.

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

К счастью, WordPress достаточно гибок для того, чтобы позволить пользователю использовать свой собственный механизм кэширования данных вместо стандартного. Стандартный механизм кэширования реализован в классе WP_Object_Cache и позволяет кэшировать данные только на время выполнения скрипта. Это не всегда удобно, ибо многие данные не меняются в течение долгого времени (соответственно, можно экономить на запросах). К тому же некоторые запросы, которые осуществляет WordPress, не очень хороши — они нагружают MySQL, а оптимизировать их очень трудно.

Посидев немного и подумав, я написал свою собственную замену для WP_Object_Cache: плагин называется WP File Cache.

Функциональность плагина:

  • поддержка долговременного (persistent) кэширования;
  • полная совместимость интерфейса с WP_Object_Cache;
  • кэширование данных в памяти для увеличения быстродействия;
  • Версия 0.2.1: реализация non-persistent caching для часто изменяющихся объектов.

Плагин пока находится в стадии тестирования, но его работа мне уже очень нравится :-)

Скачать WP File Cache 0.2.1.

Замечания по установке:

  1. Каталог /wp-content/plugins/file-cache/cache должен быть доступен на запись пользователю, под которым бегает web-сервер:
    [-]
    View Code Bash
    chmod -R 0777 wp-content/plugins/file-cache/cache
  2. При активации плагин копирует файл object-cache.php в каталог /wp-content/. Как следствие, каталог должен быть доступен плагину на запись.
  3. Для срочной деактивации плагина можно удалить или переименовать файл /wp-content/object-cache.php. В этом случае WordPress будет использовать встроенные механизмы кэширования.

Update: ниже приведены скриншоты, демонстрирующие эффективность плагина. Для замера количества запросов и времени их выполнения использовался плагин SqlMon, о котором я писал ранее.

  1. Кэширование полностью запрещено:
    737 запросов, 3.44 секунды
  2. Стандартный кэш WordPress:
    35 запросов, 0.09 секунды
  3. WP File Cache:
    10 запросов, 0.03 секунды

Связанные записи

Комментарии к статье "WP File Cache: замена WP_Object_Cache с поддержкой долговременного кэширования" (11) »

  1. [Июнь 12, 2008 5:26 дп] Vladimir:

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

    #1
  2. [Июнь 12, 2008 5:27 дп] Vladimir:

    С другой стороны, с пользовательским интерфейсом вроде все в порядке и данные отображаются нормально :-)

    #2
  3. [Июнь 28, 2008 9:18 дп] roose:

    Если я скажу глупость, то коммент не одобряйте :-), а если нет то отредактируете. Недавно тоже задумался над этим вопросом и прописав в wp-config строчку define('ENABLE_CACHE', true); добился уменьшения запросов на 50%.

    #3
  4. [Июнь 28, 2008 10:15 пп] Vladimir:

    Мне grep -R "ENABLE_CACHE" * ничего не вернул, возможно, что всё дело в разных версиях.

    В 2.5.x так (вся управляющая логика находится в wp-settings.php):

    1. Если определена константа WP_CACHE, то подключается файл wp-content/advanced-cache.php. Плагины тпа HyperCache используют этот файл для того, чтобы отдавать статический кэшированый контент — к БД никаких лишних запросов благодаря тому, что все необходимые данные живут в кэше;
    2. Если существует файл wp-content/object-cache.php, то WordPress использует его вместо своего wp-includes/cache.php. wp-content/object-cache.php должен поддерживать стандартный ВордПрессовский интерфейс для работы с кэшем. В частности, WP File Cache работает именно по этому принципу.
    #4
  5. [Июль 1, 2008 5:19 дп] roose:

    Мне grep -R “ENABLE_CACHE” * ничего не вернул, возможно, что всё дело в разных версиях.

    вот, вот потому что, файл cache.php в 2.5.х не более чем заглушка, он не проверяет существование константы ENABLE_CACHE. Вы сравните cache.php от 2.5.х и 2.3.3
    Но 2.5.х можно обмануть: Удаляем cache.php из 2.5.х, берем cache.php от 2.3.3 и вставляем его вместо удаленного и устанавливаем ENABLE_CACHE true.

    Пример применения(на localhost): Главная страница блога - 3 поста, до замены файлов - 15 запросов после замены - 4 запроса

    #5
  6. [Июль 1, 2008 8:47 пп] Vladimir:

    Вы сравните cache.php от 2.5.х и 2.3.3

    Сравнил, diff приаттачен.

    файл cache.php в 2.5.х не более чем заглушка

    На самом деле нет - в ветке 2.5.x кэширование полностью переписано. И реализовано иначе. Если вкратце, то в 2.5 кэш разрешен по умолчанию, и запретить его не так-то просто (фактически, нужно писать свой плагин, который будет игнорировать запросы на кэширование).

    Если есть желание попробовать 2.5 с отключенным кэшем, то нужно внести небольшую поправку в файл wp-includes/cache.php:

    [-]
    View Code PHP
    1.     function get($id, $group = 'default') { /*
    2.         if (empty ($group))
    3.             $group = 'default';
    4.  
    5.         if (isset ($this->cache[$group][$id])) {
    6.             $this->cache_hits += 1;
    7.             return $this->cache[$group][$id];
    8.         }
    9.  
    10.         if ( isset ($this->non_existant_objects[$group][$id]) )
    11.             return false;
    12.  
    13.         $this->non_existant_objects[$group][$id] = true;
    14.         $this->cache_misses += 1; */
    15.         return false;
    16.     }

    Но это будет очень жестоко :-)

    cache.diff

    #6
  7. [Июль 2, 2008 5:14 дп] roose:

    Если кеш по умолчанию в 2.5.x включен, то почему не видно его работы, ни уменьшения кол-ва запросов, ни папки с кешируемыми данными?

    #7
  8. [Июль 2, 2008 2:56 пп] Vladimir:

    ни папки с кешируемыми данными

    Потому что TTL кэша — один запрос (в смысле, HTTP request): то есть скрипт закончил работу, кэш сбросился. Как следствие, все кэшированые данные живут в памяти.

    В ветке 2.3 использовалась блокировка файла для ограничения доступа к кэшу, что вызывало опеределённые трудности при большом количестве одновременных соединений.

    Потом 2.5 написан довольно-таки своеобразно: если не кэшировать данные из файла в память (двойное кэширование), то производительность падает.

    то почему не видно его работы, ни уменьшения кол-ва запросов

    Я использовал плагин SqlMon для тестирования. Результаты сейчас выложу в статью, так будет нагляднее.

    #8
  9. [Июль 3, 2008 5:12 дп] roose:

    Спасибо за объяснения, приятно было с Вами побеседовать :-)

    #9
  10. [Август 15, 2008 7:30 пп] Vladimir:

    Появилась версия 0.2 плагина WP File Cache.

    Добавлены функции для более комфортной работы в WordPress 2.6; как следствие, устранены недостатки, связанные с отдачей устаревших данных (особенно это касается панели администратора).

    Скачать WP File Cache.

    #10
  11. [Ноябрь 14, 2008 7:30 пп] Vladimir:

    Появилась версия 0.2.1 плагина WP File Cache, исправляющая ошибки в реализации non-persistent caching.

    Скачать WP File Cache.

    #11

RSS лента комментариев к этой записи. TrackBack URL

Оставить комментарий к записи "WP File Cache: замена WP_Object_Cache с поддержкой долговременного кэширования"

Изображения должны быть включены!

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя