WordPress как на ладони
rgbcode is looking for WordPress developers.

Объектный кэш

Object cache или Кэш объектов в WordPress — это механизм ядра, который позволяет сохранять любые данные в кэш. Такой кэш используется для сохранения данных, которые получаются много раз в процессе кода или для сохранения данных полученных после сложных операций.

Пример объектного кэширования

Рассмотрим пример кэширования SQL запроса.

Допустим, у нас есть следующая функция. Если вызвать эту функцию несколько раз подряд, то она каждый раз будет выполнять запрос в базу данных.

function myfunc() {
	return $wpdb->get_results( "SELECT ..." );
}

myfunc(); // SQL запрос
myfunc(); // SQL запрос
myfunc(); // SQL запрос

Сделаем, чтобы функция работала с объектным кэшем. И теперь только первый вызов функции выполнит SQL запрос, а остальные будут брать данные из кэша.

function myfunc() {
	global $wpdb;

	// пробуем получить кэш и вернем его если он есть
	$cache_key = 'my_cache_key';
	$cache = wp_cache_get( $cache_key );

	if( false !== $cache )
		return $cache;

	$value = $wpdb->get_results( "SELECT ..." );

	wp_cache_set( $cache_key, $value ); // добавим данные в кэш

	return $value;
}

myfunc(); // SQL запрос
myfunc(); // Кэш
myfunc(); // Кэш

Объектное кэширование в WordPress

В 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 esc_html( $post->post_title ) . '<br>';
}

// дальше в коде нам нужны метаданные поста 3

echo get_post_meta( 3, 'my_meta', 1 ); // эти данные будут взяты из кэша.

Постоянное кэширование объектов

По умолчанию кэширование объектов в WordPress непостоянно — это значит, что оно работает внутри одного HTTP запроса (только на генерацию одной страницы) и не работает между разными запросами (при посещении новой страницы, кэш со старой страницы не используется). По ходу генерации страницы данные сохраняется в кэш (оперативную память) и берутся от туда, когда дальше в коде опять запрашиваются эти же данные. Например, поэтому функция get_option() не делает каждый раз запрос в БД при очередных вызовах, а берет данные уже из кэша объектов.

В WordPress есть возможность включить внешнее хранилище для кэша объектов и таким образом сделать объектное кэширование постоянным. Так данные из кэша будут работать между запросами.

Для включения постоянного объектного кэша (persistent object cache) нужно установить плагин. Таких плагинов несколько, потому что вариантов где хранить такой кэш тоже несколько, вот некоторые из них:

Для того, чтобы определить используется ли постоянное кэширование. WordPress использует функцию wp_using_ext_object_cache(). Она полезна для разработчиков, когда надо выполнять разные действия при наличии или отсутствии плагина кэширования.

Например, сохраним значение в кэш объектов, только если кэш является постоянным, в противном случае сохраним значение в файл:

if( wp_using_ext_object_cache() ){
	wp_cache_set( 'key', 'value' );
}
else {
	// ваш код для сохранения данных в файл
}

Группы

Параметр $group у функций кэширования позволяет использовать одинаковые ключи кэша.

Группа — это префикс к ключу. Такой префикс используется:

  • при работе с WordPress мультисайт («глобальные» и «не глобальные» группы).
  • при использовании плагинов объектного кэширования («постоянные» и «непостоянные» группы).

В WordPress используются следующие названия групп (вы также можете использовать их если они подходят логически, иначе назвать группу как-то по-своему):

Название группы Описание
(taxonomy)_relationships массив term_id
count хранит счетчики
category -
posts хранит записи (посты)
comment группа кэша для комментариев.
default группа кэша по умолчанию.
options группа кэша для хранения опций.
themes группы кэша для хранения тем.
plugins группы кэша для хранения плагинов.
users группа кэша для хранения информации о юзерах.
userlogins -
useremail -
userslugs -
transient хранит временные опции - set_transient()
networks -
blog-details -
site-options -
sites найденные сайты
site-transient хранит временные опции - set_site_transient()
customize_changeset_post -
oembed_cache_post -
timeinfo -
calendar -

Глобальные группы (для мультисайта)

Работают только когда 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
themes

В список глобальных групп можно добавить свою группу, см. функцию wp_cache_add_global_groups('my-global-group').

Непостоянные группы

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

Иногда надо, чтобы кэш не сохранялся на постоянной основе, а работал как и прежде (только во время генерации страницы). Чтобы добиться этого, можно указать группу для создаваемого кэша объектов и пометить эту группу как «Непостоянная». Делается это с помощью функции wp_cache_add_non_persistent_groups( 'my-group' ).

Так при сохранении кэша в группе «my-group», значение будет сохранено только в локальный кэш (в оперативную память) и не будет сохраняться в хранилище кэширующего плагина, например на сервер Memcached.

Обычно к непостоянным группам относятся группы:

counts
plugins
themes

Отключение кэша объектов

Отключение для участка кода

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

С помощью функции wp_suspend_cache_addition() можно временно отключить работу объектного кэша.

wp_suspend_cache_addition( true ); // отключаем работу кэша объектов

// наш код...

wp_suspend_cache_addition( false ); // включаем обратно

Полное отключение объектного кэширования

Плагины объектного кэширования добавляют специальный файл object-cache.php. Чтобы отключить работу такого плагина налету можно использовать хук enable_loading_object_cache_dropin:

add_filter( 'enable_loading_object_cache_dropin', '__return_false' );

Хук появился в версии WP 5.8. Срабатывает до подключения плагинов и нужен когда код запускается не с веба, например при тестах.

Как проверить включен ли объектный кэш?

Сделать это можно с помощью функции wp_using_ext_object_cache():

if ( wp_using_ext_object_cache() ) {

	// добавляем данные в кэш
}

PHP Функции

wp_cache_get( $key, $group, $force, $found )
Получает данные из объектного кэша по указанным ключу и группе.
wp_cache_add( $key, $data, $group, $expire )
Добавляет данные в кэш, если кэша с указанным ключом еще нет.
wp_cache_set( $key, $data, $group, $expire )
Добавляет данные в кэш объектов. Перезапишет кэш, если он существует.
wp_cache_replace( $key, $data, $group, $expire )
Заменяет/обновляет данные указанного кэша, только если кэш уже существует, в противном случает ничего не делает (вернет false).
wp_cache_delete( $key, $group )
Удаляет кэш по указанному ключу и группе.
wp_cache_flush( )
Полностью очищает объектный кэш. Удаляет все элементы объектного кэша.
wp_cache_flush_group( $group )
Removes all cache items in a group, if the object cache implementation supports it.
wp_cache_add_global_groups( $groups )
Добавляет указанную группу объектного кэша в список глобальных групп. Нужно для мультисайта.
wp_cache_add_non_persistent_groups( $groups )
Помечает указанную группу/группы как непостоянный кэш, т.е. который не нужно сохранять для межсессионного использования.
wp_suspend_cache_addition( $suspend )
Временно приостанавливает добавление объектов в объектный кэш.
wp_using_ext_object_cache( $using )
Проверят включен ли плагин (дополнительный код) для постоянного кэширования объектов.
wp_cache_supports( $feature )
Determines whether the object cache implementation supports a particular feature.
Функции-обертки:
wp_cache_get_multiple( $keys, $group, $force )
Retrieves multiple values from the cache in one call.
wp_cache_add_multiple( $data, $group, $expire )
Adds multiple values to the cache in one call.
wp_cache_set_multiple( $data, $group, $expire )
Sets multiple values to the cache in one call.
wp_cache_delete_multiple( $keys, $group )
Deletes multiple values from the cache in one call.
wp_cache_flush_runtime( )
Полностью очищает объектный кэш, только если он хранится в памяти (не используется постоянное кэширование). При постоянном кэшировании ничего не делает.

Полный список функций кэша объектов.

Дебаг объектного кэша

Чтобы посмотреть как используется кэш можно установить плагин «Debug Bar». В нём можно посмотреть статистику обращений в кэш объектов и потребляемую память (сколько весит элемент кэша).

Если установлен плагин кэширования объектов, Debug Bar покажет данные по внешнему серверу.

--

При написании использовал материал с сайта wpmag.ru.

12 комментариев
Полезные 2Вопросы 1 Все
    Войти