Как работает кеширование в Bitrix? Всё просто

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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. Заключение

Смысл статьи не в научном открытии или какой-то доселе неведомой технологии, а демонстрации простоты решений.

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

Если у вас есть примеры, как можно использовать данный стандартный функционал, то пишите комментарии. Если есть примеры нестандартных решений — делитесь опытом.

Источник: https://habr.com/ru/post/590029/


Интересные статьи

Интересные статьи

Часть 1 Часть 2 Часть 3 В этой статье вы узнаете: -О том, что такое transfer learning и как это работает -О том, что такое semantic/instance segmentation и как это работает ...
Ранее в одном из наших КП добавление задач обрабатывалось бизнес-процессами, сейчас задач стало столько, что бизнес-процессы стали неуместны, и понадобился инструмент для массовой заливки задач на КП.
Если у вас есть интернет-магазин и вы принимаете платежи через Интернет, то с 01 июля 2017 года у вас есть онлайн-касса.
Рассказываем, как создать простое приложение для расчета чаевых на языке Kotlin. Если точнее, то Kotlin 1.3.21, Android 4, Android Studio 3. Статья будет интересной, в первую очередь, для тех, ...
Автокэширование в 1с-Битрикс — хорошо развитая и довольно сложная система, позволяющая в разы уменьшить число обращений к базе данных и ускорить выполнение страниц.