Ошибки удаления кэша битрикс

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

Что такое кэш и для чего нужно кэширование?

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

Когда браузер запрашивает веб-страницу, сервер выполняет множество сложных вычислений. Он находит последние записи, генерирует подвал и шапку сайта, ищет виджеты боковых панелей и т.д. Кэширование позволяет запомнить окончательный результат и не обрабатывать каждый запрос по отдельности.

Сайт, собранный и реализованный надлежащим образом, загружается всего за пару секунд. Но даже в этом случае следует использовать кэширование. Так вы сократите время загрузки, где каждая секунда сказывается на уровне конверсии.

Нет времени разбираться?

Техподдержка сайта на «1С-Битрикс» под ключ

Специализируемся на «1С-Битрикс» более 10 лет и знаем все подводные камни и специфику. Работаем с сайтами любой технической сложности и бизнес-логики. При необходимости подключаем UX-специалиста и дизайнера. В течение 2 часов реагируем на обращения в тикетной системе.

Ваш сайт:

1С-Битрикс имеет производительную систему кэширования. Она применяется в стандартных компонентах Битрикс, но может использоваться при самостоятельной разработке. Основная ее задача – понизить время отклика сайта и увеличить его устойчивость при нагрузках. Для реализации кэширования в системе есть два класса:

  • CPageCache — для кэширования HTML результата выполнения скрипта.
  • CPHPCache — для кэширования HTML и PHP переменных.

Каждый класс имеет несколько собственных методов.

CPhpCache

Класс CPhpCache, необходимый для кэширования PHPпеременных и HTMLрезультата реализации скрипта, включает 8 основных методов:

  • StartDataCache. Этот метод ответственен за инициализацию механизма кэширования и запуск буферизации. Вторая функция — вывод содержимого из кэша.
  • EndDataCache. Сохраняет PHP переменные файлы кэша и буферизированный HTML.
  • InitCache. Подготавливает механизм кэширования. Выполняет проверку на наличие валидного и неистекшего файла кэша. При обнаружении такого файла происходит его подключение.
  • GetVars. Ответственен за возвращение PHP переменных, сохраненных в кэше.
  • Output. Выводит результат, сохраненный в кэше HTML.
  • IsCacheExpired. Этот метод доступен с версии Битрикс 3.3.7. Проверяет продолжительность жизни кэша.
  • CleanDir. Доступен с версии 8.5.1. Ответственнен за очистку кэша по параметру basedir.
  • AbortDataCache. Отменяет создание текущего кэша.

Пример кэширования HTMLи PHPпеременных выглядит следующим образом:

GetUserGroupString(); 
 
// если кэш есть и он ещё не истек то
if($obCache->InitCache($life_time, $cache_id, "/")):
// получаем закэшированные переменные
    $vars = $obCache->GetVars();
$SECTION_TITLE = $vars["SECTION_TITLE"];
else :
// иначеобращаемсякбазе
    $arSection = GetIBlockSection($SECTION_ID);
    $SECTION_TITLE = $arSection["NAME"];
endif;
 
// добавляем пункт меню в навигационную цепочку
$APPLICATION->AddChainItem($SECTION_TITLE, $SECTION_URL."SECTION_ID=".$SECTION_ID);
 
// начинаем буферизирование вывода
if($obCache->StartDataCache()):
 
// выбираем из базы параметры элемента инфоблока
if($arIBlockElement = GetIBlockElement($ELEMENT_ID, $IBLOCK_TYPE)):
echo"
"; print_r($arIBlockElement); echo"

";
endif;

// записываем предварительно буферизированный вывод в файл кэша
// вместе с дополнительной переменной
$obCache->EndDataCache(array(
"SECTION_TITLE" => $SECTION_TITLE
));
endif;
?>

Здесь кэшируется HTMLи PHP переменная $SECTION_TITLE. Тип и структура PHP переменных произвольные.

Что следует делать для отключения кэша на одной странице? Авторизуйтесь с административными правами и вызовите нужную страницу параметром

&clear_cache=Y (переменная clear_cache_session). Чтобы отключить кэш для всех страниц, просмотренных в рамках сессии, вызовите любую страницу параметром &clear_cache_session=Y.

Привлекли 35.000.000 людей на 185 сайтов

Мы точно знаем, как увеличить онлайн–продажи

Применяем лучшие практики digital–продвижения как из вашей тематики, так и из смежных областей бизнеса. Именно это сделает вас на голову выше конкурентов и принесёт лиды и продажи.

Ваш сайт:

CPageCache

Этот класс использует все те же методы, что и CPhp, за исключением GetVars, CleanDir и AbortDataCache. Пример кэширования HTML с помощью класса CpageCache выглядит следующим образом:

GetUserGroupString(); 
 
// инициализируембуферизированиевывода
if($obCache->StartDataCache($life_time, $cache_id, "/")):
 
// выбираем из базы параметры элемента инфоблока
if($arIBlockElement = GetIBlockElement($ELEMENT_ID, $IBLOCK_TYPE)):
echo"
"; print_r($arIBlockElement); echo"

";
endif;

// записываем предварительно буферизированный вывод в файл кэша
$obCache->EndDataCache();

endif;
?>

Метод StartDataCache ищет валидный и не истекший файл кэша, подключает его и выводит на экран. В ином случае включается буферизация. Задается интервал времени в секундах, в течение которого файл кэша будет не истекшим и валидным. Ее результаты записываются в файл кэша методом EndDataCache. Этот же параметр сохраняет идентификатор конкретного экземпляра кэша. Если какие-то переменные способны повлиять на итог выполнения кэшируемого кода, то их значения включаются в этот идентификатор.

Почему разрастается папка кэша?

Результаты кэширования сохраняются в виде файлов в каталоге /bitrix/cache/. Если время кэширования не истекло, то вместо ресурсоемкого кода подключается заранее созданный файл кэша. Однако следует помнить, что неразумное использование кэширования приведет к серьезному разрастанию размера каталога /bitrix/cache/. Что делать в такой ситуации? Для начала стоит разобраться с основными причинами.

Очень большой и сложный сайт

Одной из причин увеличения объема папки кэша может быть большой вес вашего сайта. Допустим, интернет-магазин имеет 10 тысяч товаров в одной категории. При этом на одной странице размещено 10 товаров, а ее вес составляет 10Кб кэша. Если кэшировать каждую страницу по отдельности, то размер данных будет слишком большим. При 10 тыс. единиц по 10Кб получится 100Мб. При этом размер может быть и больше – тут все зависит от типа и особенностей верстки.

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

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

Неправильно определено время кэширования

Вторая популярная проблема связана с неграмотным расчетом времени кэширования. Допустим, у вас установлено время жизни кэша на 3 месяца. При этом за все это время на него никто не зашел. Особенно это проблемно при объемном кэше. Например, его размер – от 500Кб до 1 Мб. Храниться он будет довольно долго, даже если к нему не было обращения.

Решение тут простое: нужно грамотно подобрать время кэширования и расставить параметры компонентов. Возможно, время придется сократить, а некоторые данные и вовсе не кэшировать.

Неправильно настроен кэш собственных или битриксовых компонентов

Чтобы не возникало проблем с объемами данных, заранее проверяйте параметры кэширования в компонентах. Ошибки могут быть как в собственных, так и в стандартных настройках. Внимательно изучите, на основе чего формируются собственные компоненты. В некоторых случаях их придется переписать.

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

Ошибка с механизмом очищения кэша

Еще одна причина разрастания данных, которая решается сокращением времени кэширования и проверкой всех параметров. Например, кэш не успевает удаляться, из-за чего накапливается в больших объемах. Как следствие – порождение дублей одного и того же кэша в разных компонентах.

Как сбросить кэш?

Чтобы почистить кэш Битрикс, необходимо зайти в панель администратора, раздел «Автокэширование» — «очистка файлов кэша». Далее нужно удалить все файлы в папке /bitrix/cache/.

Очистка файлов кэша в Битрикс
Очистка файлов кэша в Битрикс

Второй вариант – удаление данных в панели инструментов для конкретной страницы:

Удаление кэша для конкретной страницы в Битрикс
Удаление кэша для конкретной страницы в Битрикс

Наконец, в настройках компонента для конкретного компонента:

Настройка кэша компонента в Bitrix
Настройка кэша компонента в Bitrix

Для композитного сайта можно сбросить кэш в разделе «Настройки» — «Настройки продукта» — «Композитный сайт» — «Страницы».

Об особенностях внедрения этой технологии мы писали в статье об оптимизации сайта на «Битриксе».

Есть еще один, более простой вариант действий для сбрасывания кэша. Нужно выполнить PHP-код:

$obCache = newCPHPCache();
$obCache->CleanDir();

Все файлы кэша Битрикс будут промаркированы на удаление. Пути к файлам кэша изменятся, а значит, весь старый кэш сайта попросту не будет восприниматься. Это можно считать за моментальную очистку кэша. Останется лишь удалить указанные файлы.

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

Настройка кэширования сайта

Система Bitrix включает разные технологии кэширования:

  • Автокэширование. Динамические компоненты, используемые для создания веб-страниц, имеют встроенную поддержку управления кэшированием. Технология включается соответствующей кнопкой на административной панели.
  • Неуправляемое кэширование. Дает возможность установить правила кэширования ресурсоемких частей страниц. Результаты кэширования сохранятся в виде файлов в каталоге bitrix/cache/. Кэш здесь не перестраивается автоматически после модификации исходных данных, а действует в течение определенного времени после создания. В связи с этим он и называется неуправляемым.
  • Управляемое кэширование. Кэшированные данные обновляются незаметно для пользователя. Происходит это по мере обновления первичных данных, то есть управляются они самими данными. Такая технология используется в основном ядре продукта.
  • Кэширование меню. Здесь используется специальный алгоритм, учитывающий, что большинство посетителей — это незарегистрированные пользователи. Кэш меню управляемый. Оно обновится, если отредактировать меню или изменить права доступа к файлам и папкам через API и административный интерфейс.

Отдельно следует обозначить кэширование графических файлов и HTML кэширование. 

Оглавление

  • Что такое кеш и для чего он нужен
  • Принцип работы кеша в Битрикс
  • Новое универстальное АПИ кеширования в Битрикс на D7
    • Получение экземпляра класса BitrixMainDataCache
  • Тегированный кеш в Битрикс D7 (он же Сache Dependencies)
    • Получение экземпляра класса taggedCache:
    • Стандартные теги в Битрикс
    • Что делать, если тегов не хватает
  • Управляемый кеш (managed cache)
    • Получение экземпляра класса managedCache:
  • Кеширование ORM запросов и Highload блоков.
    • Что не так с HL блоками
  • Старый API кеширования
    • Получение экземпляра класса CPHPCache
    • Получение экземпляра класса CPageCache:
  • Кеш в компонентах
    • Работа с кешем в инфоблоке с большим количеством записей
  • Проблема чрезмерного роста кеша
    • Рост кеша меню
  • Сброс кеша в Битрикс
    • Через админку
    • Удалить кеш кнопкой на эрмитаже
    • Сбросить кеш програмно
    • Другие варианты сброса кеша
  • Другое
    • Что за папки /bitrix/cache/js и /bitrix/cache/css
    • Для чего глобальная переменная $CACHE_MANAGER
    • Объем кеша: 0 Б при работе memcached.
    • Про кеширование в браузере

Что такое кеш и для чего он нужен

Кеш — специальная область на диске или в операционной памяти компьютера, предназначенная для временного хранения информации и для часто используемых данных и команд. Чаще всего используют файловый кеш, так как он самый простой. Обработанные данные сохраняются в файл на диске, и в будущем данные не обрабатываются, а сразу читаются готовые из этого файла.

При разработке приложений чаще всего узким местом является база данных. Когда данных в таблице много, чтение одних и тех же данных происходит часто — имеет смысл запоминать готовые выборки.

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

Чтобы снизить нагрузку на сервер и ускорить страницу, оптимальным вариантом является сохранить результат всех выборок из базы данных и выводить пользователям уже сгенерированный заранее контент. А кеш обновлять только при добавлении новостей.

Как работает кеширование в Битрикс

Принцип работы кеша в Битрикс

В битрикс есть несколько реализаций кеша:

  • Единый класс в новом API D7 BitrixMainDataCache
  • Классы из старого ядра:
    — CPageCache — для кеширования только HTML
    — CPHPCache — для кеширования HTML и переменных

В начале использования кеша мы должны:

  1. Указать время кеширования. По истечению этого срока, старый кеш удалится и создастся новый.
  2. Указать имя кеша и папку хранения. Имя — уникально для каждого элемента, папка может быть общей для однотипных элементов. Удалив нужную папку, мы удалим весь кеш какой-то сущности.

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

При следующем обращении к функционалу, логика запущена не будет, а результат будет получен от предыдущего выполнения. В этом случае сохраняются ресурсы сервера, а клиент получает ответ быстрее.

Группируются данные по папкам. Если у нас кеша много, но очищать надо всё разом — мы можем сохранять всё в одной папке.

Еще в Битрикс можно помечать кеш тегами.

От одной сущности в базе данных может зависеть много файлов кеша и при её редактировании, надо обновить все данные. Чтобы не помнить все зависимости сущности, кеш при создании можно помечать тегами.

Тегированный кеш в Битрикс

В новом API D7 в Битрикс появился замечательный класс BitrixMainDataCache. Он позволяет кешировать HTML вывод и переменные.

Пример работы с классом:

use BitrixMainDataCache;

$cache = Cache::createInstance(); // Служба кеширования

$cachePath = 'mycachepath'; // папка, в которой лежит кеш
$cacheTtl = 3600; // срок годности кеша (в секундах)
$cacheKey = 'mycachekey'; // имя кеша

if ($cache->initCache($cacheTtl, $cacheKey, $cachePath))
{
    $vars = $cache->getVars(); // Получаем переменные
    $cache->output(); // Выводим HTML пользователю в браузер
}
elseif ($cache->startDataCache())
{
    $vars = [
        'date' => date('r'),
        'rand' => rand(0, 9999), // Если данные закешированы - число не будет меняться
    ];
    
	echo '<b>Какие-то данные выводятся пользователю (Если кеш не работает, то это число будет меняться: '.rand(0, 9999).')</b>';
	
    // Если что-то пошло не так и решили кеш не записывать
    $cacheInvalid = false;
    if ($cacheInvalid)
    {
        $cache->abortDataCache();
    }
    
    // Всё хорошо, записываем кеш
    $cache->endDataCache($vars);
}

// Данные будут обновляться раз в час
print_r($vars);

Чтобы проверить что всё действительно работает:

  1. Создайте новую страницу на сайте
  2. В контент вставьте код, который выше
  3. Откройте страницу в своем браузере (проверьте чтобы в адресной строке не было параметра clear_cache)
  4. Вы увидите что числа, которые в коде заданы случайными, замирают и не обновляются с обновлением страницы. Это потому что код выполнился 1 раз и результат сохранился.
  5. Если на панели эрмитажа нажать Сбросить кеш — то цифры обновятся

Работа кеширования HTML в Битрикс

Числа, на которые указывают стрелки не обновляются при обновлении страницы.

Получение экземпляра класса BitrixMainDataCache

$cache = BitrixMainDataCache::createInstance()

Методы класса BitrixMainDataCache

Статические методы:

  1. BitrixMainDataCache::createInstance() — создает объект для последующей работы не статических методов.
  2. BitrixMainDataCache::clearCache($initDir) — очищает кеш в папке /bitrix/cache/$initDir.

Не статические методы:

  1. $cache->initCache($TTL, $uniqueString, $initDir = false, $baseDir = «cache») — инициализация кеша. Проверяет существование кеша, вычитывает данные.

    $TTL — время жизни в секундах
    $uniqueString — уникальное имя
    $initDir — папка, где будет кеш (внутри $baseDir). Если не указать, то будет браться из текущей запрошенной страницы -> для каждой отдельной страницы будет создаваться новый кеш, хотя данные там одни и те же -> объем кеша будет огромный, а пользы будет мало. Рекомендуется всегда указывать папку.
    $baseDir — папка, внутри /bitrix. Менять не рекомендуется, потому что кеш должен храниться в /bitrix/cache.

  2. $cache->startDataCache($TTL = false, $uniqueString = false, $initDir = false, $vars = array(), $baseDir = «cache») — начинает процесс кеширования. Дальше данные, которые выводятся в браузер, будут записываться (используется буфер вывода PHP).

    Все параметры как у initCache, только есть еще $vars
    $vars — переменные, которые сохранятся в кеш. Далее в коде переменные можно еще передать в endDataCache(). Параметр избыточный, передавать сюда данные не рекомендуется.

    Если вы вызывали initCache(), то параметры в startDataCache() передавать уже не стоит, вызывайте без параметров.

  3. $cache->abortDataCache() — останавливает кеширование.
  4. $cache->endDataCache($vars = false) — сохраняет кеш.

    $vars — переменны, которые стоит сохранить. Если переменные передаются сюда, то переданные в startDataCache() — игнорируются.

  5. $cache->output() — выводит в браузер HTML из кеша.
  6. $cache->getVars() — получает переменные из кеша.
  7. $cache->clean($uniqueString, $initDir = false, $baseDir = «cache») — удаляет кеш с именем $uniqueString в папке $initDir.
  8. $cache->cleanDir($initDir = false, $baseDir = «cache») — удаляет весь кеш в папке $initDir.

Мы можем не использовать вызов $cache->output(), если работаем только с переменными. Если работаем только с HTML — так же можем не вызывать $cache->getVars().

HTML не требуется передавать в какую-то функцию, чтобы он попал в кеш, просто отдавайте в браузер. Переменные можно сохранять не только скалярные, а все, которые можно сериализовать (массивы, объекты…) (О сериализации на php.net).

Хранение кеша по умолчанию в /bitrix/cache.

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

Тегированный кеш в Битрикс D7 (он же Сache Dependencies)

В дополнение к основному классу кеширования, есть служба для установки тегов на кеш.

Рассмотрим пример с инфоблоком. Есть инфоблок Новости (ID 4), данные из него выводятся на главной странице, на странице списка новостей, так же для каждой новости есть детальная страница. Это всё отдельные файлы кеша. Когда мы добавляем какую-то новость, мы не знаем кеш каких страниц надо сбросить. API инфоблока говорит сбросить кеш по тегу iblock_id_4, а к тегу уже привязаны десятки файлов, которые удаляются.

Своего кеша у taggedCache нет, теги хранятся в базе данные в таблице b_cache_tag.

Пример работы кеширования с тегами:

use BitrixMainDataCache;
use BitrixMainApplication;

$cache = Cache::createInstance(); // Служба кеширования
$taggedCache = Application::getInstance()->getTaggedCache(); // Служба пометки кеша тегами

/*
 * Чтобы тегированный кеш нашел что ему сбрасывать, необходим
 * одинаковый путь в $cache->initCache() и  $taggedCache->startTagCache()
 * У нас путь указан в $cachePath
 */
$cachePath = 'mycachepath';
$cacheTtl = 3600;
$cacheKey = 'mycachekey';

if ($cache->initCache($cacheTtl, $cacheKey, $cachePath)) {
    $vars = $cache->getVars();

    /*
     * Еще тут можно вывести данные в браузер, через $cache->output();
     * Тогда получится замена классу CPageCache
     */
} elseif ($cache->startDataCache()) {
    // Начинаем записывать теги
    $taggedCache->startTagCache($cachePath);
    $vars = [
        'date' => date('r'),
        'rand' => rand(0, 9999), // Если данные закешированы - число не будет меняться
    ];

    // Добавляем теги

    // Кеш сбрасывать при изменении данных в инфоблоке с ID 1
    $taggedCache->registerTag('iblock_id_1');

    // Кеш сбрасывать при изменении данных в инфоблоке с ID 2
    $taggedCache->registerTag('iblock_id_2');

    // Если что-то пошло не так и решили кеш не записывать
    $cacheInvalid = false;
    if ($cacheInvalid) {
        $taggedCache->abortTagCache();
        $cache->abortDataCache();
    }

    // Всё хорошо, записываем кеш
    $taggedCache->endTagCache();
    $cache->endDataCache($vars);
}

// Данные будут обновляться раз в час или при обновлении данных в инфоблоках 1 и 2
print_r($vars);

Очистка кеша по тегу:

use BitrixMainApplication;

$taggedCache = Application::getInstance()->getTaggedCache(); // Служба пометки кеша тегами

/*
 * Где-то на отдельной странице чистим кеш по тегу.
 * В данному случае очистится кеш, который зависит от 2 инфоблока
 */
$taggedCache->clearByTag('iblock_id_2');

Получение экземпляра класса taggedCache:

$taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();

Методы класса тегированного кеша

  1. $taggedCache->startTagCache($relativePath) — путь, который будет очищаться при удалении кеша по тегу. Путь передавать тот же, что и в $cache->initCache().
  2. $taggedCache->endTagCache() — окончание. Сохраняет привязку путей к тегам в базу данных.
  3. $taggedCache->abortTagCache() — останавливает кеширование. Вызывать когда запущено кеширование, но оно уже не требуется.
  4. $taggedCache->registerTag($tag) — привязывает тег к пути кеша, указанному ранее при вызове startTagCache().
  5. $taggedCache->clearByTag($tag) — очистка кеша по тегу.

Стандартные теги в Битрикс

Модуль Универсальные списки (lists)
LISTS_ELEMENT_LIVE_FEED — помечается, но не чистится
lists_list_{$iblockId} — очищается при редактировании списка, который работает через инфоблок $iblockId
lists_list_any — чистится при редактировании любого списка

Модуль Веб-мессенджер (im)
IM_CONTACT_LIST — при изменении цвета статуса пользователя

Модуль Блог (blog)
blog_post_{$postId} — при изменении поста
blog_post_getsocnetperms_{$postId} — при изменении прав поста (при присваивании определенным постам привязок к рабочим группам)

Модуль Обучение (learning)
{$entityTypeId}{$entityId} — при добавлении оценки сущностям, чьи $entityTypeId равны LEARN_CHAPTER, LEARN_LESSON, LEARN_COURSE. LEARN_COURSE{$courseId} — При обновлении курса
LEARNING_GROUP_{(int) $groupId / 100} — обновление кеша сотни группы. При добавлении/изменении/удалении группы
LEARNING_GROUP — При добавлении/изменении/удалении групп

Модуль rest
bitrix24_left_menu — при смене прав приложения через BitrixRestAppTable::setAccess()

Модуль wiki
wiki_{$wikiId} — при изменении вики страницы

Модуль forum
forum_{$forumId}
forum_topic_{$topicId}
forum_msg_count{$forumId} — при изменений сообщений форума

Модуль инфоблоков (iblock)
iblock_property_enum_{$propertyId} — при изменении свойства типа перечисление
iblock_id_new — при добавлении инфоблоков
iblock_id_{$iblockId} — при изменении инфоблока

Модуль социальной сети (socialnetwork)
SONET_LOG_{$logId} — при изменении записи в живой ленте
sonet_features_{$entityType}_{$entityId} — при добавлении функционала группе sonet_feature_{$featureId} — при добавлении права на функционал
sonet_features2perms_{$permId} — при удалении права на функционал
sonet_search_{$entityType}_{$entityId}
sonet_user2group_G{$groupId} — при изменении членства пользователей в группах. При удалении группы sonet_user2group_U{$userId} — при изменении членства пользователей в группах
sonet_user2group — при изменении членства пользователей в группах. При удалении группы sonet_group_view_U{$userId}
sonet_group_{$groupId} — при удалении группы
sonet_group — при удалении группы
sonet_group_activity — при установке активности группы
sonet_subscription_{$subscriptionCode} — при добавлении, обновлении подписки. При удалении подписки с указанием кода. При удалении через указание ID не вызывается
sonet_subscription — при удалении всех подписок некоего пользователя
SONET_LOG_FOLLOW_{$userId} — при изменении подписок пользователя в живой ленте
blogpost_important_all — при редактировании важных записей
{$optionName}{$postId} — при редактировании опций блога пользователя
{$optionName}{$postId}_{$userId}} — при редактировании опций блога пользователя {$optionName}_USER_{$userId}} — при редактировании опций блога пользователя

Модуль calendar
calendar_user_{$userId} — при изменении событий в календаре пользователя
CALENDAR_EVENT_LIST — при изменении раздела в календаре

Модуль Интернет магазин (sale)
sale-location-data — при изменении местоположений

Главный модуль (main)
RV_CACHE — при удалении пользователем оценки
{$componentName} — при очистке кеша компонента
USER_CARD_{$chunkNum} — при изменении пользователя, где $chunkNum = (int) $userId / TAGGED_user_card_size; Кеш не на отдельных пользователей, а на пачку
USER_CARD — при редактировании пользователя с битриксовой авторизацией
EXTERNAL_USER_CARD — при редактировании пользователя с внешней авторизацией
USER_NAME_{$userId} — при изменении пользователя. При обновлении может вызываться не всегда, а только если передано хотя бы одно из следующих полей: NAME, LAST_NAME, SECOND_NAME, ACTIVE, LOGIN, EMAIL, PERSONAL_GENDER, PERSONAL_PHOTO, WORK_POSITION, PERSONAL_PROFESSION, PERSONAL_WWW, PERSONAL_BIRTHDAY, TITLE, EXTERNAL_AUTH_ID, UF_DEPARTMENT, AUTO_TIME_ZONE, TIME_ZONE, TIME_ZONE_OFFSET

Модуль голосований (vote)
vote_form_channel_{$voteId} — при изменении каналов голосования
vote_form_vote_{$voteId} — при изменении голоса, вопросов
vote_form_question_{$voteId} — при изменении вопросов, ответов
vote_form_answer_{$voteId} — устаревшее

Модуль landing
landing_page_{$landingId} — при изменении лендинга

Модуль веб форм (form)
form_{$formId} — при изменении формы, где {$formId} — ID формы.

Что делать, если тегов не хватает

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

Например, нам нужен сброс кеша при редактировании сайтов.

Добавим в init.php такой код:

AddEventHandler("main", "OnSiteDelete", "clearSiteCacheByTag", 10000);
AddEventHandler("main", "OnBeforeSiteAdd", "clearSiteCacheByTag", 10000);
AddEventHandler("main", "OnBeforeSiteUpdate", "clearSiteCacheByTag", 10000);

function clearSiteCacheByTag() {
	$taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();
	$taggedCache->clearByTag('site_edit');
}

Теперь при создании, обновлении и удалении сайтов будет удаляться весь кеш по тегу site_edit.

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

Почему этот кеш называется управляемый — не ясно, управлять им особо не выходит. Managed cache в Битрикс это такая прослойка над обычным классом кеширования для более быстрой работы и компактного кода. Используется чаще всего для кеширования выборок отдельных таблиц.

Сразу начну с минусов:

  1. К этому кешу не привязать теги (без горы костылей).
  2. В старых версиях (где-то до 19 версии) при вызове cleanAll() управляемого кеша, удаляется так же весь кеш, на который установлены теги.

Простой пример работы с классом:

$managedCache = BitrixMainApplication::getInstance()->getManagedCache();

$uniqId = 'my_cache_key'; // ключ, по которому сохраняем и получаем данные
$ttl = 30; // время жизни кеша

$managedCache->read($ttl, $uniqId); // считываем кеш с диска

$res = $managedCache->get($uniqId); // получаем данные из считанного файла
if ($res === false) { // если данных нет
    $res = date('r'); // то генерируем данные, тут, например, у нас тяжелая логика

    $managedCache->set($uniqId, $res); // сохраняем данные (пока будут храниться в памяти)
}

var_dump($res); // работаем с данными

В примере выше всё просто. Считываем данные, если их нет — с помощью какой-то вашей тяжелой логики генерируем, сохраняем в кеш. В следующий раз, когда данные понадобятся, если срок годности кеша еще не истечет, то получим их из кеша, сэкономив ресурсы.

Сохранение данных на диск происходит в эпилоге битрикс (заключительная часть после отработки логики страницы). Если данные большие, имеет смысл вместо функции set() использовать setImmediate(), которая сразу сохраняет данные и очищает память.

Крупные недочеты:

  1. Пока на диске есть кеш по вашему ключу, новые данные сохранить не получится. Надо сперва удалить старые, а потом вызвать read(), хотя мы точно знаем что данных нет. Read() надо вызывать, потому что там устанавливается ttl, а он обязателен для сохранения.
  2. В функции getImmediate() требуется указывать ttl, хотя он не используется. TTL нужен только при сохранении кеша. При том TTL не хватает при вызове setImmediate(), там то он нужен. Но так как setImmediate() не принимает в параметрах TTL, перед его вызовом требуется вызов read() для указания TTL.

В остальном работать можно.

Получение, замена кеша с использованием get/set функций.

$managedCache = BitrixMainApplication::getInstance()->getManagedCache();

$uniqId = 'my_table2';
$ttl = 30;

$managedCache->read($ttl, $uniqId);

// Получить данные из заранее считанного файла
$res = $managedCache->get($uniqId);
var_dump($res);

$dataIsValid = false;
if (!$dataIsValid) {
    $managedCache->clean($uniqId);
    $managedCache->read(900, $uniqId);

    // Сохранит в файл при окончании работы скрипта Битрикс
    $managedCache->set($uniqId, [
        'data_table_2' => rand(0, 999) . date(' :: r'),
    ]);
}

Получение, замена кеша с использованием getImmediate/setImmediate функций.

$uniqId = 'my_table3';
$ttl = 30;

// Считать файл и получить данные. Информация о считанном файле не сохраняется, поэтому, если вы захотите записать данные, придется всё равно вызывать read(). $ttl тут ни на что не влияет, параметр этот лишний
$res = $managedCache->getImmediate($ttl, $uniqId);
var_dump($res);

$dataIsValid = false;
if (!$dataIsValid) {
    // Вызов clean() очищает ресурсы после работы, поэтому если хотите после работать с кешем, то надо заново вызывать read()
    $managedCache->clean($uniqId);
    $managedCache->read(900, $uniqId);

    // Сохранит в файл немедленно. Перед этим вызовом обязателен вызов read()
    $managedCache->setImmediate($uniqId, [
        'data_table_3' => rand(0, 999) . date(' :: r'),
    ]);
}

Получение экземпляра класса managedCache:

$managedCache = BitrixMainApplication::getInstance()->getManagedCache();

Методы класса BitrixMainDataManagedCache:

  1. $managedCache->read($ttl, $uniqueId, $tableId = false) — читает файл кеша, на случай если мы какие-то данные добавим. $ttl — время жизни, $uniqueId — уникальное имя, $tableId — папка в которой сохранится файл (относительно /bitrix/managed_cache). Папку указывать не обязательно.
  2. $managedCache->getImmediate($ttl, $uniqueId, $tableId = false) — получение данных из кеша без предварительного считывания. $ttl — ни на что не влияет, не понятно для чего добавили его, остальное как в пункте 1.
  3. $managedCache->get($uniqueId) — получить данные, которые должны быть предварительно считаны с помощью read функции из пункта 1.
  4. $managedCache->set($uniqueId, $val) — добавление данных по имени $uniqueId. Чтобы данные добавились и сохранились, предварительно надо вызвать read из пункта 1. Значение может быть как скалярным значением, так и другим, которое можно сериализовать (О сериализации на php.net). Данные сохраняются на диск при подключении эпилога.
  5. $managedCache->setImmediate($uniqueId, $val) — установка значения с последующим моментальным сохранением данных на диск, предварительно должна быть вызвано read(). Буфер при этом очищается и если вы снова захотите работать с $uniqueId, то надо будет вызвать заново read().
  6. $managedCache->clean($uniqueId, $tableId = false) — удаление кеша по имени и папке
  7. $managedCache->cleanDir($tableId) — удаление всех кешей в папке
  8. $managedCache->cleanAll() — удаление всего управляемого кеша. Где-то до 19 версии битрикс удаляется почему-то еще и весь тегированный кеш.
  9. BitrixMainDataManagedCache::finalize() — сохранение данных на диск. Автоматически вызывается в эпилоге битрикса.

Кеширование ORM запросов и Highload блоков.

При разработке модулей часто требуется хранение данных в базе данных, операции при этом одни и те же: Create, Read, Update, Delete (создание, чтение, обновление и удаление данных). Для быстрой работы с новыми таблицами и стандартизированного подхода создан ORM. Оно надо чтобы не писать каждый раз заново логику валидации данных, генерацию запросов, API получения данных, создания событий.

Для реализации этих целей введены понятия:

  1. Cущности (BitrixMainEntityBase);
  2. Поля сущностей (BitrixMainEntityField и его наследники);
  3. Датаменеджер (BitrixMainEntityDataManager).

Сущность описывает таблицу в БД. Датаменеджер производит операции выборки и изменения сущности.

Более подробно можно почитать в курсе битрикса про ORM. А мы рассмотрим кеш.

D7 классы можно определить по наличию пространства имен, которое отделяется обратными слешами от имени класса. Например, в старом API работа с группами пользователей идет через класс CGroup, в новом же через BitrixMainGroupTable. Наличие символов «» говорит нам о том, что это новый API. В D7 большинство сущностей построено на основе ORM, а это нам говорит что наконец у всех классов единая сигнатура методов. Больше не будет такого у что одних первый параметр это сортировка, у других сортировка это второй параметр, а первый это фильтр…

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

$res = BitrixMainGroupTable::getList([
    'cache' => ['ttl' => 3600],
]);

При добавлении/изменении/удалении данных кеш автоматически сбрасывается.

Что не так с HL блоками

Хайлоад блоки тоже работают на основе ORM, та же сигнатура методов, но вот методы изменения данных переопределены и сброс кеширования туда не добавлен! Почему? Загадка…

То есть используете вы код:

$hlbl = 2; // Указываем ID нашего highloadblock блока к которому будет делать запросы.
$hlblock = BitrixHighloadblockHighloadBlockTable::getById($hlbl)->fetch();
$entity = BitrixHighloadblockHighloadBlockTable::compileEntity($hlblock);

$entity_data_class = $entity->getDataClass();

$rsData = $entity_data_class::getList([
    'cache' => ['ttl' => 360000],
]);

while($arData = $rsData->Fetch()){
    var_dump($arData);
}

Изменяете как-то данные, а кеш по прежнему дает вам устаревшие значения до тех пор, пока не истечет срок его годности.

Решается проблема добавлением такого кода в init.php:

$eventManager = BitrixMainEventManager::getInstance();

$eventManager->addEventHandler('', 'BrandReferenceOnAfterAdd', 'clearBrandReferenceCache');
$eventManager->addEventHandler('', 'BrandReferenceOnAfterUpdate', 'clearBrandReferenceCache');
$eventManager->addEventHandler('', 'BrandReferenceOnAfterDelete', 'clearBrandReferenceCache');

function clearBrandReferenceCache($event)
{
    $event->getEntity()->cleanCache();
}

Где BrandReference — имя вашего HL блока. Данный код удаляет кеш HL блока после изменения данных.

Я бы такое событие повесил сразу на все хайлоад блоки, но так не получается, надо знать и перечислять все имена блоков.

Старый API кеширования

Использовать уже не стоит эти старые классы, есть удобные новые. Описываю для пониманию работы старого кода. Вместо единого нового класса есть 2 старых: CPageCache — для кеширования только HTML, — CPHPCache — для кеширования HTML и переменных.

Получение экземпляра класса CPHPCache

$obCache = new CPHPCache;

Методы CPHPCache:

  1. $obCache->InitCache($TTL, $uniq_str, $initdir=false, $basedir = «cache») — проверяет наличие кеша на диске, инициализирует параметры. Переданные сюда параметры можно уже не передавать в StartDataCache().
  2. $obCache->StartDataCache($TTL=false, $uniq_str=false, $initdir=false, $vars=Array(), $basedir = «cache») — где
    $TTL — время жизни кеша
    $uniq_str -имя
    $initdir — папка относительно $basedir
    $vars — переменные, которые в будущем могут сохраниться в кеш
    $basedir — папка относительно /bitrix, лучше не трогать
  3. $obCache->EndDataCache($vars=false) — завершает кеширование. Сохраняет HTML вывод, который был после начала кеширования, и переменные из $vars на диск.
  4. $obCache->GetVars() — получает сохраненные переменные из кеша.
  5. $obCache->Output() — выводит сохраненный в кеше HTML.
  6. $obCache->AbortDataCache() — отменяет начатое кеширование.

Пример работы с классом:

// создаем объект
$obCache = new CPHPCache;

// время кеширования - 30 минут
$life_time = 30*60;

// формируем идентификатор кеша в зависимости от всех параметров
// которые могут повлиять на результирующий HTML
$cache_id = $ELEMENT_ID.$USER->GetUserGroupString();

if($obCache->InitCache($life_time, $cache_id, "/")) {
    // получаем закешированные переменные
    $vars = $obCache->GetVars();

    // выводим на экран содержимое кеша
    $obCache->Output();
} else if ($obCache->StartDataCache()) {
    $vars = [
        /* какие-то данные, например, из базы */
    ];

    echo '<b>Какие-то данные, которые попадут в кеш</b>';
    
    $obCache->EndDataCache($vars);
}

В CPageCache всё аналогично классу CPHPCache, только нет работы с переменными.

Получение экземпляра класса CPageCache:

$obCache = new CPageCache;

Методы класса:

  1. $obCache->InitCache($TTL, $uniq_str, $initdir = false, $basedir = «cache»)
  2. $obCache->StartDataCache($TTL, $uniq_str=false, $initdir=false, $basedir = «cache»)
  3. $obCache->EndDataCache()
  4. $obCache->Output()
  5. $obCache->AbortDataCache()

Кеш в компонентах

На основе описанных ниже принципов работают все стандартные компоненты и некоторые от самостоятельных разработчиков. Раздел описывает логику таких компонентов, как bitrix:news.list, bitrix:news.detail, bitrix:catalog.section, bitrix:catalog.element и других.

Для работы кеша в параметры вызова компонента добавляются параметры:

"CACHE_GROUPS" => "N", // Для разных групп пользователей - один кеш
"CACHE_TIME" => "36000000", // Время кеширования в секундах
"CACHE_TYPE" => "A", // Тип кеширования. N - выключено, A - включено, кеш автоматически сбрасывается при изменении данных, Y - включено, но кеш сам не сбрасывается

Важно понимать, что комплексные компоненты не используют кеширование. Они принимают запросы и распределяют между простыми компонентами, которые в свою очередь уже кешируют данные.

В компоненте, если предусмотрено кеширование, всегда вызывается метод startResultCache() класса CBitrixComponent. Внутри этого метода, если включено в параметрах вызова компонента, запускается кеширование (обычное и сразу тегированное). Теги нигде тут не устанавливаются.

Если в кешируемой области используется получение данных из инфоблоков, то теги на инфоблок устанавливаются внутри метода Fetch() API инфоблока. Метод GetNext() тоже работает поверх Fetch(), так что тоже ставит тег. Поэтому при работе с инфоблоками, дополнительно ставить теги не требуется.

Если требуется установить дополнительные теги в компоненте, то делать это стоит после вызова startResultCache() и до includeComponentTemplate().

В общем виде код компонента выглядит так:

<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();

/*
 * Валидация параметров
 */

if(!isset($arParams["CACHE_TIME"]))
    $arParams["CACHE_TIME"] = 36000000;

$arParams["IBLOCK_TYPE"] = trim($arParams["IBLOCK_TYPE"]);
$arParams["IBLOCK_ID"] = trim($arParams["IBLOCK_ID"]);
$arParams["SORT_BY1"] = trim($arParams["SORT_BY1"]);

// Требуется для того, чтобы кеширование сохранило данные из $arResult
$arResult = &$this->arResult;

/*
 * Начало кеширования
 * 
 * Если кеш уже существует - startResultCache() возвращает false,
 * заполняет $arResult, выводит верстку.
 */
if($this->startResultCache(...))
{
    /*
     * Код тут выполняется только когда нет кеша
     */
    $iterator = CIBlockElement::GetList(...);
    
    /*
     * При вызове GetNext() кеш помечается тегом инфоблока
     */
	while ($arItem = $iterator->GetNext()) {
        $arResult['ITEMS'][] = $arItem;
    }
	$this->setResultCacheKeys(array(
		"ID",
		"IBLOCK_TYPE_ID",
		"NAME",
		"SECTION",
		"ELEMENTS",
	));
	$this->includeComponentTemplate();
}

/*
 * Устанавливаются параметры, которые надо выполнять всегда, в независимости от наличия кеша
 */
$APPLICATION->SetTitle($arResult["NAME"]);

Кеширование завершается и сохраняется на диск внутри вызова CBitrixComponent::includeComponentTemplate() . Записывается HTML вывод шаблона, данные из $arResult (по фильтру указанному при вызове CBitrixComponent::setResultCacheKeys()), а так же адреса стилей, файлов js, component_epilog.php, в том числе от вложенных компонентов.

Так как шаблон подключается внутри секции кеширования, в нем тоже можно вызывать CBitrixComponent::setResultCacheKeys(), указывать теги и даже отменять кеширование.

В шаблоне компонента можно создать файлы script.js и style.css. Они будут подключаться автоматически при подключении компонента. Их подключение будет происходить даже когда компонент закеширован.

Методы класса компонентов для кеширования:

Методы класса используются одни и те же что при работе через файл component.php, что через class.php. В случае работы через class.php используются $this->arResult и $this->arParams.

  1. $this->startResultCache($cacheTime = false, $additionalCacheID = false, $cachePath = false) — проверяет наличие кеша компонента, если есть, то заполняет переменную $arResult, выводит HTML в браузер и возвращает false. Если кеша нет, то начинает кеширование, запускает тегированный кеш, возвращает true.
    Так же возвращает true, но не начинает кеширование при выключенном кешировании или если кеширование выбрано авто, но в настройках отключено кеширование компонентов.

    $cacheTime — время кеширования, если передано false, то берется из $arParams[‘CACHE_TIME’]
    $additionalCacheID — кеш зависит от текущего сайта ( SITE_ID), имени компонента, имени шаблона, входных параметров $arParams. Если кеш должен зависеть от каких-либо дополнительных параметров, то их необходимо передать сюда в виде строки.
    $cachePath — Путь к файлу кеша относительно папки кешей. По умолчанию равен «/».SITE_ID.<путь к компоненту относительно bitrix/components>/<еще какая-то строка зависящая от переменной состояния>.

  2. $this->endResultCache() — завершает кеширование, сохраняет кеш на диск, запоминая в том числе HTML вывод шаблона и $arResult. Автоматически вызывается при вызове $this->includeComponentTemplate().
  3. $this->abortResultCache() — завершает кеширование, данные на диск не сохраняет. Метод на случай если кеширование запущено, но произошла ошибка и стоит прервать операцию.
    Если начать кеширование и не завершить его, появится множество багов.
  4. $this->setResultCacheKeys($arResultCacheKeys) — принимает массив ключей по которому будет фильтрация данных в $arResult. Позволяет кешировать не весь результат, а только нужные данные.
    При повторном вызове не затирает старые ключи, а дополняет их.
  5. $this->getCacheID($additionalCacheID = false) — генерирует имя кеша. Если переопределить в своем классе и указывать $cachePath, можно добиться того, что кеш не будет зависеть от текущего сайта.
    $additionalCacheID — данные из вызова startResultCache()
  6. $this->clearResultCache($additionalCacheID = false, $cachePath = false) — чистит кеш компонента, параметры аналогичны startResultCache(). Вместо вызова этой функции, пользуйтесь тегированным кешем.
  7. $this->clearComponentCache($componentName, $siteId = «») — очищает кеш по имени компонента.

Пример работы с кешем в компоненте при работе через class.php:

<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

class MyComponent extends CBitrixComponent
{

    public function executeComponent()
    {
        if ($this->startResultCache()) {

            if (empty($this->arParams['KEY'])) {
                // Если требуется отменить кеш
                $this->AbortResultCache();
                ShowError('Не установлен ключ');
                return;
            }

            /* Тут какая-то логика по заполнению $this->arResult */
            

            $this->arResult['CITY'] = 'Ижевск';

            $this->IncludeComponentTemplate();
        }
    }

}

Чтобы в настройках компонента появилась вкладка с настройками кеширования достаточно добавить параметр CACHE_TIME:

$arComponentParameters = array(
    "PARAMETERS" => array(
        // KEY - какой-то наш параметр, к кешу отношения не имеет
        "KEY" => array(
            "NAME" => "API ключ",
            "TYPE" => "STRING",
            "GROUP" => "BASE",
            "DEFAULT" => "",
        ),

        // Говорим что компонент работает с кешем
        "CACHE_TIME" => array("DEFAULT" => "3600"),
    ),
);

Важно: при подключении в шаблоне других вложенных компонентов, указывайте вышестоящий через четвертый параметр IncludeComponent(). В файле template.php ссылка на вышестоящий компонент в переменной $component. Иначе у вложенного компонента будут проблемы с подключением стилей, скриптов и component_epilog.php.

$APPLICATION->IncludeComponent($componentName, $componentTemplate, $arParams, $parentComponent)

Важно. Если вложенный компонент использует кеширование, выключайте его в параметрах вызова. Во-первых вложенный кеш полностью бесполезен, во-вторых он вреден, так как теги вложенного компонента не установятся на актуальный кеш.

Интересно:

  1. В шаблоне компонента можно отменить запись кеша, а так же добавить теги на кеш.
  2. Если вложенные компоненты не используют кеширование, их вывод всё равно будет закеширован в основном компоненте. После этого result_modifier.php и template.php вызываться не будут, работать будет component_epilog.php.
  3. Кеш зависит от параметров вызова компонента. Если в параметрах у вас динамические данные, то для каждого варианта будет свой кеш, в этом случае бывает выгоднее просто не использовать кеширование.
  4. Если вы хотите взаимодействовать из шаблона иным способом, нежели вывод HTML, то делайте это через файл component_epilog.php. Например, не получится устанавливать заголовок страницы из template.php, этот файл 1 раз закешируется и заголовок устанавливаться больше не будет.

Работа с кешем в инфоблоке с большим количеством записей

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

Чтобы решить эту проблему, придется отказаться от стандартного тега. Использовать будем только result_modifier.php и init.php.

Наш план:

  1. Вызов компонента оставить с типом кеширования — Авто
  2. В result_modifier.php сбросить стандартный тег, установить свой.
  3. В init.php добавить события для сброса кеша по своему тегу.

Если делать отдельный тег для каждого элемента, то это будет слишком накладно. Можно сделать лучше: поделить все записи на чанки, например, по 500 элементов и уже на эти отдельные блоки ставить теги.

Формула для получение тега конкретного элемента:

define('IBLOCK_CHUNK_SIZE', 500);

$iblockId = 5;
$elementId = 10;

$tag = 'iblock_id_' . $iblockId . '_chunk_' . intval($elementId / IBLOCK_CHUNK_SIZE);

Для элементов с ID 1-499 тег будет iblock_id_5_chunk_0, для 500-999 iblock_id_5_chunk_1 и так далее. Но этот тег не получится добавить на страницы списка. Потому что при добавлении или удалении новости на первой странице, происходит сдвиг записей на всех страницах пагинации. При обновлении записи может измениться сортировка и опять же сдвинутся все страницы списка. Поэтому, менять принцип кеширования страниц списка нет смысла.

Работать будем с компонентами news.list и news.detail. В случае каталога — действия те же, просто обхватить надо большее количество шаблонов и событий для сброса кеша.

В result_modifier.php шаблона детальной новости добавьте код:

if ($arParams['CACHE_TYPE'] === 'A') {
    $taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();
    $taggedCache->abortTagCache(); // сбрасываем стандартные теги

    $tag = 'iblock_id_' . $arParams['IBLOCK_ID'] . '_chunk_' . intval($arResult['ID'] / IBLOCK_CHUNK_SIZE);

    $taggedCache->startTagCache($this->__component->getCachePath());
    $taggedCache->registerTag($tag); // Ставим свой тег
}

Выше мы остановили тегированный кеш, чтобы сбросить установленные стандартные теги. После начали его заново и установили свой тег. Завершит тегированный кеш уже битрикс, так как он начинал его.

При добавлении данного алгоритма на страницы списка могут появиться баги на сайте, смотрите по вашей ситуации.

В result_modifier.php шаблона news.list добавьте:

if ($arParams['CACHE_TYPE'] === 'A') {
    $taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();
    $taggedCache->abortTagCache();

    $taggedCache->startTagCache($this->__component->getCachePath());

    foreach ($arResult['ITEMS'] as $arItem) {
        $tag = 'iblock_id_' . $arParams['IBLOCK_ID'] . '_chunk_' . intval($arItem['ID'] / IBLOCK_CHUNK_SIZE);
        $taggedCache->registerTag($tag);
    }
}

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

В init.php добавьте код:

define('IBLOCK_CHUNK_SIZE', 500);

AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "ClearIblockCacheHandler");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "ClearIblockCacheHandler");
AddEventHandler("iblock", "OnAfterIBlockElementDelete", "ClearIblockCacheHandler");

function ClearIblockCacheHandler($arFields)
{
    if($arFields['IBLOCK_ID'] == 7 and (! isset($arFields["RESULT"]) or $arFields["RESULT"])) {
        $tag= 'iblock_id_' . $arFields['IBLOCK_ID'] . '_chunk_' . intval($arFields['ID'] / IBLOCK_CHUNK_SIZE);

        $taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();
        $taggedCache->clearByTag($tag);
    }
}

В коде выше 7 — это ID инфоблока в котором мы меняем теги кеша. После добавления, обновления и удаления записей — сбрасываем кеш по тегу. Сбросятся детальные новости тега и страницы списка новостей, на которых была запись.

Так же можно добавить события на сброс кеша при изменении параметров инфоблока, при изменении свойств и другое. Список всех событий есть по ссылке https://dev.1c-bitrix.ru/api_help/iblock/events/index.php

Так при обновлении одной записи сбрасывается кеш только 500 страниц, а не всех десятков тысяч.

Проблема чрезмерного роста кеша

Рост кеша меню

Частая проблема на сайтах — огромный кеш меню, хотя в нем нет много данных.

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

У компонента есть параметр CACHE_SELECTED_ITEMS, который, по не понятной причине, не выведен в настройки компонента. По умолчанию он устанавливается в Y и кеш начинает зависеть от адреса страницы.

Чтобы отключить это поведение, добавьте такой параметр в вызов меню: «CACHE_SELECTED_ITEMS» => «N»

В итоге получится у вас что-то такое:

<?$APPLICATION->IncludeComponent("bitrix:menu", "top", Array(
   "ROOT_MENU_TYPE" => "top",   // Тип меню для первого уровня
   "MENU_CACHE_TYPE" => "A",   // Тип кеширования
   "MENU_CACHE_TIME" => "3600",   // Время кеширования (сек.)
   "MENU_CACHE_USE_GROUPS" => "N",   // Учитывать права доступа
   ...
   "CACHE_SELECTED_ITEMS" => "N", // Не создавать кеш меню для каждой страницы
   ),
   false
);?>

Сброс кеша в Битрикс

Через админку

Основной способ сброса кеша находится в админке в разделе Настройки -> Настройки продукта -> Автокеширование. Вкладка Очистка файлов кеша.

Варианты очистки:

  1. Только устаревшие — удаление кеша срок годности которого уже истек. Удаляет файлы которые уже не используются.
  2. Все — всё понятно, удалить весь кеш.
  3. Меню — удалить кеш меню.
  4. Весь управляемый
  5. Все страницы HTML кеша — HTML кеш — это часть композитного кеша. Удалить эти данные.
  6. Сайты24 — удалить кеш лендингов сайтов 24.

Другие вкладки на странице:

  1. Кеширование компонентов — тут кнопка включения/выключения кеширования компонентов, но не всех, а тек у кого режим Авто + Управляемое.
  2. Управляемый кеш — включение/отключение управляемого кеша.

Выключается кеширование только для режима разработки, на боевых сайтах отключать кеширование крайне не рекомендуется.

Удалить кеш кнопкой на эрмитаже

Удалить кеш Битрикс

Нажатие кнопки на эрмитаже заставляет весь кеш на странице не видеть старые данные и создавать всё заново, после чего кеш сохраняется на диск. Важно понимать что кеш перезаписывается конкретно на вашем хите. Если у пользователей тот же кеш, то у них он тоже будет новый. А если кеш какого-то компонента зависит от групп пользователя, то у админов кеш сбросится, а у посетителей данные останутся старые.

Сбросить кеш програмно

Так же можно удалить кеш через API, но для этого надо знать как к нему обратиться.

Удалить кеш по тегу (в данном случае удалится кеш инфоблока 2):

$taggedCache = BitrixMainApplication::getInstance()->getTaggedCache();
$taggedCache->clearByTag('iblock_id_2');

Удалить кеш зная имя и папку:

$cache = BitrixMainDataCache::createInstance()
$cache->clean($uniqueString, $initDir);

Удалить весь кеш в папке:

$cache = BitrixMainDataCache::createInstance()
$cache->cleanDir($initDir);

Другие варианты сброса кеша

Если кеш удаляется через админку долго, можно ему помочь удалив файлы на сервере через SSH или FTP. Удалите вручную все файлы в папках bitrix/cache, bitrix/managed_cache.

Кеш компонентов с автокешированием, которые используют инфоблоки, можно сбросить пересохранив какой-то элемент инфоблока (того инфоблока, который выводится в компоненте).

Другое

Что за папки /bitrix/cache/js и /bitrix/cache/css

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

Для чего глобальная переменная $CACHE_MANAGER

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

Объем кеша: 0 Б при работе memcached.

Если для кеширования вы используете мемкеш, то его объем может не считаться. Это нормальная ситуация, переживать не стоит. Кеш при этом работает.

Про кеширование в браузере

Браузер кеширует статические ресурсы (стили, скрипты, картинки…). Браузер не кеширует HTML страницу. (Кеширование HTML браузером можно сделать при работе через заголовок 304 Not Modified, но такое делают редко).

Если вы добавляете скрипты через штатное API Битрикс (например $APPLICATION->AddHeadScript(), BitrixMainPageAsset::getInstance()->addCss(), файлы script.js, style.css в шаблоне…), то браузер будет сбрасывать кеш скриптов и стилей при изменении файла на сервере. Так происходит потому что Битрикс добавляет к адресу файла временную метку.

При изменении файла меняется его дата обновления, временная метка в ссылке на файл меняется, для браузера это новый файл, браузер запрашивает файл с сервера.

К картинкам временная метка не добавляется, поэтому при их обновлении могут быть проблемы.

Кеш стилей и скриптов не сбрасывается, когда вы подключаете их не через API, а тегами в шаблоне.

<script type="text/javascript" src="/bitrix/templates/books/js/script.js"></script>

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

Чтобы заставить браузер не использовать кеш, можно открыть Инстументы разработчика и на вкладке Network поставить галочку Disable cache. Пока инструменты разработчика открыты, кеш будет отключен на текущей вкладке.

Так же можно обновить вкладку сочетанием Shift + F5, тогда кеш браузера сбросится.

Пожалуйста, оцените на сколько вам понравилась статья!

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

Что такое кэш и для чего нужно кэширование?

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

Когда браузер запрашивает веб-страницу, сервер выполняет множество сложных вычислений. Он находит последние записи, генерирует подвал и шапку сайта, ищет виджеты боковых панелей и т.д. Кэширование позволяет запомнить окончательный результат и не обрабатывать каждый запрос по отдельности.

Сайт, собранный и реализованный надлежащим образом, загружается всего за пару секунд. Но даже в этом случае следует использовать кэширование. Так вы сократите время загрузки, где каждая секунда сказывается на уровне конверсии.

Нет времени разбираться?

Техподдержка сайта на «1С-Битрикс» под ключ

Специализируемся на «1С-Битрикс» более 10 лет и знаем все подводные камни и специфику. Работаем с сайтами любой технической сложности и бизнес-логики. При необходимости подключаем UX-специалиста и дизайнера. В течение 2 часов реагируем на обращения в тикетной системе.

Ваш сайт:

1С-Битрикс имеет производительную систему кэширования. Она применяется в стандартных компонентах Битрикс, но может использоваться при самостоятельной разработке. Основная ее задача – понизить время отклика сайта и увеличить его устойчивость при нагрузках. Для реализации кэширования в системе есть два класса:

  • CPageCache — для кэширования HTML результата выполнения скрипта.
  • CPHPCache — для кэширования HTML и PHP переменных.

Каждый класс имеет несколько собственных методов.

CPhpCache

Класс CPhpCache, необходимый для кэширования PHPпеременных и HTMLрезультата реализации скрипта, включает 8 основных методов:

  • StartDataCache. Этот метод ответственен за инициализацию механизма кэширования и запуск буферизации. Вторая функция — вывод содержимого из кэша.
  • EndDataCache. Сохраняет PHP переменные файлы кэша и буферизированный HTML.
  • InitCache. Подготавливает механизм кэширования. Выполняет проверку на наличие валидного и неистекшего файла кэша. При обнаружении такого файла происходит его подключение.
  • GetVars. Ответственен за возвращение PHP переменных, сохраненных в кэше.
  • Output. Выводит результат, сохраненный в кэше HTML.
  • IsCacheExpired. Этот метод доступен с версии Битрикс 3.3.7. Проверяет продолжительность жизни кэша.
  • CleanDir. Доступен с версии 8.5.1. Ответственнен за очистку кэша по параметру basedir.
  • AbortDataCache. Отменяет создание текущего кэша.

Пример кэширования HTMLи PHPпеременных выглядит следующим образом:

GetUserGroupString(); 
 
// если кэш есть и он ещё не истек то
if($obCache->InitCache($life_time, $cache_id, "/")):
// получаем закэшированные переменные
    $vars = $obCache->GetVars();
$SECTION_TITLE = $vars["SECTION_TITLE"];
else :
// иначеобращаемсякбазе
    $arSection = GetIBlockSection($SECTION_ID);
    $SECTION_TITLE = $arSection["NAME"];
endif;
 
// добавляем пункт меню в навигационную цепочку
$APPLICATION->AddChainItem($SECTION_TITLE, $SECTION_URL."SECTION_ID=".$SECTION_ID);
 
// начинаем буферизирование вывода
if($obCache->StartDataCache()):
 
// выбираем из базы параметры элемента инфоблока
if($arIBlockElement = GetIBlockElement($ELEMENT_ID, $IBLOCK_TYPE)):
echo"
"; print_r($arIBlockElement); echo"

";
endif;

// записываем предварительно буферизированный вывод в файл кэша
// вместе с дополнительной переменной
$obCache->EndDataCache(array(
"SECTION_TITLE" => $SECTION_TITLE
));
endif;
?>

Здесь кэшируется HTMLи PHP переменная $SECTION_TITLE. Тип и структура PHP переменных произвольные.

Что следует делать для отключения кэша на одной странице? Авторизуйтесь с административными правами и вызовите нужную страницу параметром

&clear_cache=Y (переменная clear_cache_session). Чтобы отключить кэш для всех страниц, просмотренных в рамках сессии, вызовите любую страницу параметром &clear_cache_session=Y.

Привлекли 35.000.000 людей на 185 сайтов

Мы точно знаем, как увеличить онлайн–продажи

Применяем лучшие практики digital–продвижения как из вашей тематики, так и из смежных областей бизнеса. Именно это сделает вас на голову выше конкурентов и принесёт лиды и продажи.

Ваш сайт:

CPageCache

Этот класс использует все те же методы, что и CPhp, за исключением GetVars, CleanDir и AbortDataCache. Пример кэширования HTML с помощью класса CpageCache выглядит следующим образом:

GetUserGroupString(); 
 
// инициализируембуферизированиевывода
if($obCache->StartDataCache($life_time, $cache_id, "/")):
 
// выбираем из базы параметры элемента инфоблока
if($arIBlockElement = GetIBlockElement($ELEMENT_ID, $IBLOCK_TYPE)):
echo"
"; print_r($arIBlockElement); echo"

";
endif;

// записываем предварительно буферизированный вывод в файл кэша
$obCache->EndDataCache();

endif;
?>

Метод StartDataCache ищет валидный и не истекший файл кэша, подключает его и выводит на экран. В ином случае включается буферизация. Задается интервал времени в секундах, в течение которого файл кэша будет не истекшим и валидным. Ее результаты записываются в файл кэша методом EndDataCache. Этот же параметр сохраняет идентификатор конкретного экземпляра кэша. Если какие-то переменные способны повлиять на итог выполнения кэшируемого кода, то их значения включаются в этот идентификатор.

Почему разрастается папка кэша?

Результаты кэширования сохраняются в виде файлов в каталоге /bitrix/cache/. Если время кэширования не истекло, то вместо ресурсоемкого кода подключается заранее созданный файл кэша. Однако следует помнить, что неразумное использование кэширования приведет к серьезному разрастанию размера каталога /bitrix/cache/. Что делать в такой ситуации? Для начала стоит разобраться с основными причинами.

Очень большой и сложный сайт

Одной из причин увеличения объема папки кэша может быть большой вес вашего сайта. Допустим, интернет-магазин имеет 10 тысяч товаров в одной категории. При этом на одной странице размещено 10 товаров, а ее вес составляет 10Кб кэша. Если кэшировать каждую страницу по отдельности, то размер данных будет слишком большим. При 10 тыс. единиц по 10Кб получится 100Мб. При этом размер может быть и больше – тут все зависит от типа и особенностей верстки.

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

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

Неправильно определено время кэширования

Вторая популярная проблема связана с неграмотным расчетом времени кэширования. Допустим, у вас установлено время жизни кэша на 3 месяца. При этом за все это время на него никто не зашел. Особенно это проблемно при объемном кэше. Например, его размер – от 500Кб до 1 Мб. Храниться он будет довольно долго, даже если к нему не было обращения.

Решение тут простое: нужно грамотно подобрать время кэширования и расставить параметры компонентов. Возможно, время придется сократить, а некоторые данные и вовсе не кэшировать.

Неправильно настроен кэш собственных или битриксовых компонентов

Чтобы не возникало проблем с объемами данных, заранее проверяйте параметры кэширования в компонентах. Ошибки могут быть как в собственных, так и в стандартных настройках. Внимательно изучите, на основе чего формируются собственные компоненты. В некоторых случаях их придется переписать.

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

Ошибка с механизмом очищения кэша

Еще одна причина разрастания данных, которая решается сокращением времени кэширования и проверкой всех параметров. Например, кэш не успевает удаляться, из-за чего накапливается в больших объемах. Как следствие – порождение дублей одного и того же кэша в разных компонентах.

Как сбросить кэш?

Чтобы почистить кэш Битрикс, необходимо зайти в панель администратора, раздел «Автокэширование» — «очистка файлов кэша». Далее нужно удалить все файлы в папке /bitrix/cache/.

Очистка файлов кэша в Битрикс
Очистка файлов кэша в Битрикс

Второй вариант – удаление данных в панели инструментов для конкретной страницы:

Удаление кэша для конкретной страницы в Битрикс
Удаление кэша для конкретной страницы в Битрикс

Наконец, в настройках компонента для конкретного компонента:

Настройка кэша компонента в Bitrix
Настройка кэша компонента в Bitrix

Для композитного сайта можно сбросить кэш в разделе «Настройки» — «Настройки продукта» — «Композитный сайт» — «Страницы».

Об особенностях внедрения этой технологии мы писали в статье об оптимизации сайта на «Битриксе».

Есть еще один, более простой вариант действий для сбрасывания кэша. Нужно выполнить PHP-код:

$obCache = newCPHPCache();
$obCache->CleanDir();

Все файлы кэша Битрикс будут промаркированы на удаление. Пути к файлам кэша изменятся, а значит, весь старый кэш сайта попросту не будет восприниматься. Это можно считать за моментальную очистку кэша. Останется лишь удалить указанные файлы.

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

Настройка кэширования сайта

Система Bitrix включает разные технологии кэширования:

  • Автокэширование. Динамические компоненты, используемые для создания веб-страниц, имеют встроенную поддержку управления кэшированием. Технология включается соответствующей кнопкой на административной панели.
  • Неуправляемое кэширование. Дает возможность установить правила кэширования ресурсоемких частей страниц. Результаты кэширования сохранятся в виде файлов в каталоге bitrix/cache/. Кэш здесь не перестраивается автоматически после модификации исходных данных, а действует в течение определенного времени после создания. В связи с этим он и называется неуправляемым.
  • Управляемое кэширование. Кэшированные данные обновляются незаметно для пользователя. Происходит это по мере обновления первичных данных, то есть управляются они самими данными. Такая технология используется в основном ядре продукта.
  • Кэширование меню. Здесь используется специальный алгоритм, учитывающий, что большинство посетителей — это незарегистрированные пользователи. Кэш меню управляемый. Оно обновится, если отредактировать меню или изменить права доступа к файлам и папкам через API и административный интерфейс.

Отдельно следует обозначить кэширование графических файлов и HTML кэширование. 

Есть блок, генерируемый через js, изменяю этот скрипт, выполняю очистку кеша кнопкой «сбросить кеш» и ничего не меняется. Изменяю файл кеша, само-собой изменяется, удаляю файл кеша — всё по старому. То же самое если обновлять кеш самой страницы в браузере

Изменяю точно нужный файл, тк выкачал все файлы, сделал по ним поиск через sublime, повторение нужного кода на весь проект одно
Может кто-нибудь сталкивался и может подсказать?

Материал из Wiki — Iphoster — the best ever hosting and support. 2005 — 2023

Перейти к:навигация, поиск

Доступная цена

Bitrix — Работа с файлами кеша — Ошибка! Не работает

Если при тестировании возникает ошибка вида:

Работа с файлами кеша - Ошибка! Не работает 

то нужно проверить права на папку: bitrix/cache/ и поставить ей права 777:

# chmod 777 bitrix/cache/

Источник — https://wiki.iphoster.net/index.php?title=Bitrix_-_Работа_с_файлами_кеша_-_Ошибка!_Не_работает&oldid=9530

1С-Битрикс.
Есть инфоблок. Задача: Вывести на страницу текст из свойства элемента.

Написал собственный компонент. Допустим так (укорочено для простоты):

// class.php
<?php
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

use BitrixMainLocalizationLoc;
Loc::loadMessages(__FILE__);

class ProductText extends CBitrixComponent
{
    public function executeComponent()
    {
        if($this->startResultCache()) {
        // или if($this->startResultCache($this->arParams['CACHE_TIME'], false, 'product.text/')) {

            if(!BitrixMainLoader::includeModule('iblock')) {
                $this->abortResultCache();
            }

            $iblock = BitrixIblockIblock::wakeUp($this->arParams['IBLOCK_ID']);
            $entity = $iblock->getEntityDataClass();

            $rs = $entity::getList(
                [
                    'filter' => $this->getFilter(),
                    'select' => $this->getSelect(),
                ],
            )->fetchObject();

            $this->arResult['ID'] = $rs->getId();
            $this->arResult['TEXT'] = $rs->getText() ? $rs->getText()->getValue() : '';

            if(empty($this->arResult)) {
                $this->abortResultCache();
            }
            
            $this->includeComponentTemplate();
        }
    }

    protected function getFilter() {...}
    protected function getSelect() {...}
}

Вызывается компонент просто:

$APPLICATION->IncludeComponent(
    "pppp:product.text", 
    ".default", 
    array(
        "IBLOCK_ID" => "9",
        "ID" => "46211",
        "COMPONENT_TEMPLATE" => ".default",
        "COMPOSITE_FRAME_MODE" => "A",
        "COMPOSITE_FRAME_TYPE" => "AUTO",
        "CACHE_TYPE" => "A",
        "CACHE_TIME" => "604800"
    ),
    false
);

Все работает, компилируется нужный шаблон с данными, кешируется, выводится;

Но если мы изменим название элемента инфоблока или значение в строковом свойстве элемента, то ничего не меняется, данные берутся из кеша. Только ручной сброс кеша помогает. Но хотелось бы автоматического…

Автокеширование включено, кеширование включено, композит выключен.
Почему не срабатывает автоматический сброс кеша при Автокешировании?

  • Ошибки уаз патриот 3163
  • Ошибки туарег 2003 на табло
  • Ошибки трк шайтан бахман
  • Ошибки триколор тв описание
  • Ошибки тренера при проведении тренинга