1. Введение
Данная статья — это не научный прорыв, а лишь помощник, чтобы быстрее понять, как работает стандартный функционал в Bitrix.Давайте представим, что в разделе каталога у нас 150 запросов к БД. Вроде бы немного при условии, если в один момент обращение к разделу происходит одним пользователем?
При одновременном обращении к разделу 200-т пользователей количество запросов равняется 200 * 150 = 30 000
Кеширование помогает снизить нагрузку на БД и сервер в целом.
Не судите за то, что я использую старое ядро в примере. Суть данной статьи показать, как это работает и потребности темы полностью покрываются.
2. Простое кеширование
//CPhpCache - класс для кеширования PHP переменных и HTML результата выполнения скрипта.CModule::IncludeModule("main");
$arFilter = array(
"IBLOCK_ID" => 17,
"ACTIVE" => "Y",
"GLOBAL_ACTIVE" => "Y",
);
$obCache = new CPHPCache();
/**
Первый аргумент отвечает за время жизни кеша
Второй аргумент - это хеш кеша. Например если в двух компонентах одинаковые запросы, то и кеш у них будет общий. Достаточно набрать кеш в одном компоненте.
Третий аргумент - это место хранения кеша. Путь не относительно корня сайта, а относительно папки с кешем. Для компонента каталог путь такой - /iblock/catalog
/
if($obCache->InitCache(36000, serialize($arFilter), "/iblock/catalog"))
{
//Если кеш существует, то его результат сразу будет выдан и не надо выполнять код с запросами к БД
$arCurSection = $obCache->GetVars();
}else{ //Если кеша нет, то выполнится код и сформируется кеш. В дальнейшем будет отдаваться переменная из кеша, а не выполняться этот код
$arCurSection = array();
$dbRes = CIBlockSection::GetList(array(), $arFilter, false, array("ID"));
if(!$arCurSection = $dbRes->GetNext()){
$arCurSection = array();
}
//$arCurSection - передаем в кеш переменную с полученными в коде значениями
$obCache->EndDataCache($arCurSection);
}
Результат выполнения кода — это переменная $arCurSection со значениями полученными из кеша или запросов к БД.
Проблема данного метода в том, что если что-то изменится в инфоблоке, то результат будет нерелевантным. Решение данной проблемы описано в пункте 3.
3. Тегированный кеш
Для того, чтобы решить проблему описанную в пункте 2, надо почистить директорию с кешем /iblock/catalog (путь не относительно корня сайта, а относительно папки с кешем) в момент добавления, изменения, удаления элементов инфоблока и связанных с ним сущностей, которые выводит наш компонент.Для того, чтобы не изобретать «городушки» для сброса кеша при изменениях, был придуман тегированный кеш.
Для того, чтобы месту хранения кеша присвоить кеш используем это:
/**
/iblock/catalog - место хранения кеша
"iblock_id_17" - тег для места хранения кеша
/
global $CACHE_MANAGER;
$CACHE_MANAGER->StartTagCache("/iblock/catalog");
$CACHE_MANAGER->RegisterTag("iblock_id_17");
$CACHE_MANAGER->EndTagCache();
Сброс кеша по тегу можно осуществить следующим способом:
/**
"iblock_id_17" - тег для места хранения кеша
/
global $CACHE_MANAGER;
$CACHE_MANAGER->ClearByTag("iblock_id_17");
В итоге нам нужно лишь в нужный момент (навесить на события) сделать сброс кеша по тегу.
Например, в стандартных компонентах, использующих инфоблок, используется тег вида «iblock_id_17» и по этому тегу вызывается метод сброса кеша, который вызывается в методах добавления, изменения, удаления элемента инфоблока.
CModule::IncludeModule("iblock");
CIBlock::clearIblockTagCache($zr['IBLOCK_ID']);
Метод из ядра битрикс использующий ClearByTag:
//\bitrix\modules\iblock\classes\general\iblock.php
public static function clearIblockTagCache($iblock_id)
{
global $CACHE_MANAGER;
$iblock_id = (int)$iblock_id;
if (defined("BX_COMP_MANAGED_CACHE") && $iblock_id > 0 && self::''isEnabledClearTagCache''())
$CACHE_MANAGER->ClearByTag('iblock_id_'.$iblock_id);
}
4. Пример нестандартного использования кеша в каталоге
Когда мы знаем, как работает кеширование, то можем легко доработать кеширование у стандартного компонента каталога.Косяк стандартного решения — при изменении какого-либо элемента сбрасывается весь кеш (элементы, разделы).
Чтобы не заставлять систему лишний раз делать запросы, производить расчеты и набирать кеш, можно для головных разделов предусмотреть отдельный кеш. Вывести из под общего тега-инфоблока.
Тут единственная трудность в том, что бы хорошенечко подумать, в каких местах стоит так сделать.
5. Заключение
Смысл статьи не в научном открытии или какой-то доселе неведомой технологии, а демонстрации простоты решений.Да, я коснулся лишь малой части кеширования. Для простоты восприятия пусть будет этот минимум.
Как работает кеширование в Bitrix? Всё просто
1. Введение Данная статья — это не научный прорыв, а лишь помощник, чтобы быстрее понять, как работает стандартный функционал в Bitrix. Давайте представим, что в разделе каталога у нас 150 запросов к...
habr.com