Object cache или Кэш объектов в WordPress — это механизм ядра, который позволяет сохранять любые данные в кэш. Такой кэш используется для сохранения данных, которые получаются много раз в процессе кода или для сохранения данных полученных после сложных операций.
Рассмотрим пример кэширования SQL запроса.
Допустим, у нас есть следующая функция. Если вызвать эту функцию несколько раз подряд, то она каждый раз будет выполнять запрос в базу данных.
function myfunc() { return $wpdb->get_results( "SELECT ..." ); } myfunc(); // SQL запрос myfunc(); // SQL запрос myfunc(); // SQL запрос
Сделаем, чтобы функция работала с объектным кэшем. И теперь только первый вызов функции выполнит SQL запрос, а остальные будут брать данные из кэша.
function myfunc() { // пробуем получить кэш и вернем его если он есть $cache_key = 'my_cache_key'; if( $cache = wp_cache_get( $cache_key ) ) return $cache; $value = $wpdb->get_results( "SELECT ..." ); wp_cache_set( $cache_key, $value ); // добавим данные в кэш return $value; } myfunc(); // SQL запрос myfunc(); // Кэш myfunc(); // Кэш
В WP такое кэширование используется практически везде: в опциях, записях, терминах, у пользователей, метаданных и т.д.
Кэширование объектов в опциях WordPress
Для примера, рассмотрим как работает кэширование объектов в опциях WordPress. Функция get_option()
не создает дополнительных запросов в базу данных при множественном вызове, как раз благодаря такому кэшу.
При первом вызове функции get_option()
срабатывает функция wp_load_alloptions(), которая загружает в объектный кэш из базы данных все опции сайта помеченные как autoload
. Поэтому любые следующие вызовы функции get_option()
уже не будут делать запросы к БД, а будут получать данные из кэша.
Так например, этот код вызванный в файле темы не сделает ни одно запроса к БД:
if( ! get_option( 'comments_open' ) ){ echo '<p>Комментирование на сайте '. get_option('blogname') .' закрыто.</p>'; echo '<p>Свяжитесь с администрацией: '. get_option('admin_email') .'</p>'; }
Кэширование метаданных
По такой же логике работает и кэш метаданных. Например, при запросе записей через get_posts()
, в кэш помещаются данные поста и его метаданных и поэтому последующие обращения к данным уже полученного поста, не будут создавать дополнительные запросы в БД.
// допустим в этом запросе были получены посты: 1 2 3 4 5 $posts = get_posts(); foreach( $posts as $post ){ echo $post->post_title . '<br>'; } // дальше в коде нам нужны метаданные поста 3 echo get_post_meta( 3, 'my_meta', 1 ); // эти данные будут взяты из кэша...
По умолчанию кэширование объектов в WordPress непостоянно, т.е. работает для одного запроса (генерации одной страницы) и не работает между запросами. По ходу генерации страницы объектный кэш записывается в оперативную память и берется от туда же. Так происходит при каждом запросе.
В WordPress есть возможность включить внешнее хранилище для кэша объектов и сделать кэширование постоянным. Так данные из кэша будут доступны между запросами.
Для включения постоянного объектного кэша (persistent object cache) нужно установить плагин. Таких плагинов много, потому что вариантов где и как хранить такой кэш также много, вот некоторые из них:
Данные плагины позволяют использовать серверы Redis, Memcached, APC соответственно.
Для того, чтобы определить используется ли внешний плагин объектного кэширования, в WordPress есть специальная функция wp_using_ext_object_cache().
Она пригодится, когда надо выполнять разные действия при наличии или отсутствии плагина кэширования.
Например, сохраним значение в кэш объектов, только если кэш является постоянным, в противном случае сохраним значение в опцию:
if( wp_using_ext_object_cache() ) wp_cache_set( 'key', 'value' ); else update_option( 'key', 'value' );
Параметр $group
у функций кэширования позволяет использовать одинаковые ключи кэша.
Группа — это префикс к ключу. Такой префикс используется:
- при работе с WordPress мультисайт («глобальные» и «не глобальные» группы).
- при использовании плагинов объектного кэширования («постоянные» и «непостоянные» группы).
В ядре WordPress существуют следующие названия групп:
- default — группа кэша по умолчанию.
- posts — группа кэша для хранения записей (постов, страниц, произвольных типов).
- options — группа кэша для хранения опций.
- comment — группа кэша для комментариев.
- themes — группы кэша для хранения тем.
- plugins — группы кэша для хранения плагинов.
- users — группа кэша для хранения информации о юзерах.
Работают только когда WordPress установлен как сеть мультисайт.
К таким группам относится кэш, который является уникальным для всей сети сайтов.
Для каждого сайта сети к ключу кэша добавляется префикс сайта, чтобы отличать, например, кэш записи с ID 5 одного сайта от кэша записи с таким же ID 5 другого сайта. Но также в мультисайте есть объекты, которые работают для всей сети, например «Пользователи» — они и относятся к глобальным группам, к кэшам таких объектов никакой префикс не добавляется...
По умолчанию глобальными группами являются:
users userlogins usermeta user_meta useremail userslugs site-transient site-options blog-lookup blog-details site-details rss global-posts blog-id-cache networks sites
В список глобальных групп можно добавить свою группу, см. функцию wp_cache_add_global_groups('my-global-group')
.
По умолчанию в WordPress всё кэширование объектов непостоянное, т.е. кэширование происходит только на период генерации страницы. Но если установить плагин кэширования объектов, то кэш будет сохранятся между запросами (например в файлах) и станет постоянным.
Иногда надо, чтобы кэш не сохранялся на постоянной основе, а работал как и прежде (только во время генерации страницы). Чтобы добиться этого, можно указать группу для создаваемого кэша объектов и пометить эту группу как «Непостоянная». Делается это с помощью функции wp_cache_add_non_persistent_groups( 'my-group' )
.
Так при сохранении кэша в группе «my-group», значение будет сохранено только в локальный кэш (в оперативную память) и не будет сохраняться в хранилище кэширующего плагина, например на сервер Memcached.
Обычно к непостоянным группам относятся группы: «themes», «plugins», «comment», «counts».
Бывает нужно отключить работу объектного кэша, например, когда при импорте нужно добавить в базу большое количество записей и при обычном запуске кода процесс упирается в ограничение оперативной памяти на сервере. Происходит это потому что каждая добавляемая запись сохраняется в кэше, а нам для одноразовой операции это не нужно.
С помощью функции wp_suspend_cache_addition() можно временно отключить работу объектного кэша.
wp_suspend_cache_addition( true ); // отключаем работу кэша объектов // наш код... wp_suspend_cache_addition( false ); // включаем обратно
Чтобы посмотреть как используется кэш можно установить плагин «Debug Bar». В нём можно посмотреть статистику обращений в кэш объектов и потребляемую память (сколько весит элемент кэша).
Если установлен плагин кэширования объектов, Debug Bar покажет данные по внешнему серверу.
При написании использовал статью с сайта wpmag.ru.