Yandex Metrika
sanches.free 18 просмотров

Кеширование данных в Битрикс D7: простой, управляемый и ORM

Зачем отдельно разбирать кеш в D7

В старых проектах часто встречается CPHPCache и разрозненные обёртки. В D7 кеширование унифицировано: один стиль API, управляемый кеш с тегами и встроенная поддержка в ORM. Ниже — практические паттерны, которые можно сразу перенести в модуль или компонент.

Простой кеш: \Bitrix\Main\Data\Cache

Класс \Bitrix\Main\Data\Cache — прямой наследник идеи CPHPCache. Отличия в основном в именовании методов (CamelCase) и строгой типизации.

use Bitrix\Main\Data\Cache;

$cache = Cache::createInstance();
$cacheTtl = 7200;
$cacheId = 'catalog_sections_tree_v1';
$cacheDir = '/my_module/catalog';

if ($cache->initCache($cacheTtl, $cacheId, $cacheDir)) {
    $sections = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $sections = loadSectionsFromDb(); // тяжёлая логика
    $cache->endDataCache($sections);
}

Параметры initCache():

  • TTL — время жизни в секундах;
  • uniqueString — уникальный ключ (добавляйте версию схемы данных: _v2);
  • initDir — подпапка в /bitrix/cache/;
  • baseDir — по умолчанию cache.

Совет: не кешируйте объекты с ресурсами (соединения, файловые дескрипторы). Сохраняйте массивы и скаляры.

Управляемый кеш (ManagedCache)

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

$managedCache = \Bitrix\Main\Application::getInstance()->getManagedCache();
$cacheId = 'iblock_5_sections_list';
$cacheTtl = 3600;

if ($managedCache->read($cacheTtl, $cacheId)) {
    $sections = $managedCache->get($cacheId);
} else {
    $sections = loadSectionsFromDb();
    $managedCache->set($cacheId, $sections);
}

Принудительная очистка по ключу:

$managedCache->clean($cacheId);

Для инфоблоков удобно комбинировать с CIBlock::registerWithTagCache() или тегированным кешом компонентов — тогда сброс произойдёт при сохранении элемента без ручного clean().

Кеширование ORM-выборок

Начиная с версии 16.5.9, в getList() можно передать параметр cache. Пример для элементов инфоблока через ElementTable:

use Bitrix\Iblock\ElementTable;

$query = ElementTable::getList([
    'select' => ['ID', 'NAME', 'CODE'],
    'filter' => ['IBLOCK_ID' => 5, 'ACTIVE' => 'Y'],
    'order'  => ['SORT' => 'ASC'],
    'cache'  => [
        'ttl'         => 300,
        'cache_joins' => true,
    ],
]);

while ($row = $query->fetch()) {
    // ...
}

Кеш пишется в /bitrix/managed_cache/MYSQL/orm_* с ключом по SQL-запросу. Параметр cache_joins включает кеширование запросов с JOIN — используйте осознанно, если выборка тяжёлая.

Глобальные ограничения TTL для таблиц задаются в /bitrix/.settings.php:

'cache_flags' => [
    'value' => [
        'b_iblock_element_min_ttl' => 60,
        'b_iblock_element_max_ttl' => 86400,
    ],
],

Инвалидация кеша ORM

После массового импорта или миграции сбросьте кеш сущности:

\Bitrix\Iblock\ElementTable::getEntity()->cleanCache();

Для своих ORM-сущностей — тот же метод у YourTable::getEntity().

Что выбрать на практике

СценарийИнструмент
Результат тяжёлого PHP-расчётаData\Cache
Данные, связанные с инфоблоками/настройкамиManagedCache + теги
Частые однотипные выборки ORMcache в getList()
Вывод в компонентеКеш компонента + тегированный кеш

Типичные ошибки

  • Один ключ кеша для разных языков/сайтов — добавляйте SITE_ID и LANGUAGE_ID в cacheId.
  • Кеширование персональных данных (корзина, профиль) — только с привязкой к ID пользователя в ключе.
  • Забыли сбросить кеш после деплоя с изменением структуры — увеличивайте версию в ключе.

Итог

D7 даёт три уровня кеширования без сторонних библиотек. ManagedCache удобен для справочников и настроек, параметр cache в ORM — для стабильных выборок, а Data\Cache — для тяжёлых PHP-расчётов вне компонентов.