Разработка модуля кеширования 1С-Битрикс
У Битрикс есть собственный кеш через \Bitrix\Main\Data\Cache — файловый, с поддержкой тегов через \Bitrix\Main\Data\TaggedCache. На небольших сайтах он работает нормально. Проблемы начинаются при высокой нагрузке: тысячи файлов в /bitrix/cache/, операции чтения/записи конкурируют на файловой системе, инвалидация по тегу — блокирующая операция. Модуль кеширования надстраивает над стандартным механизмом единый слой с Redis-бэкендом, статистикой, прогревом и гранулярной инвалидацией.
Архитектура: CacheManager
Центральный класс CacheManager реализует паттерн стратегии. Бэкенд выбирается в настройках модуля:
$cache = \Vendor\Cache\CacheManager::getInstance();
// Стандартный get-or-set
$result = $cache->remember('catalog_section_12', 3600, function() {
return CIBlockSection::GetList(/* ... */)->Fetch();
}, ['iblock_12', 'catalog']);
// → Данные из кеша или результат callable, если промах
// Явная инвалидация по тегу
$cache->invalidateTag('iblock_12');
// → Сбрасываются все ключи, помеченные тегом iblock_12
Redis-бэкенд
Файловый кеш Битрикс не масштабируется на несколько серверов. Redis решает эту проблему:
class RedisCacheBackend implements CacheBackendInterface
{
private \Redis $redis;
public function get(string $key): mixed
{
$data = $this->redis->get($key);
return $data !== false ? unserialize($data) : null;
}
public function set(string $key, mixed $value, int $ttl, array $tags = []): void
{
$serialized = serialize($value);
$this->redis->setEx($key, $ttl, $serialized);
// Теги хранятся как Redis Sets
foreach ($tags as $tag) {
$this->redis->sAdd("tag:{$tag}", $key);
$this->redis->expire("tag:{$tag}", $ttl + 3600);
}
}
public function invalidateTag(string $tag): void
{
$keys = $this->redis->sMembers("tag:{$tag}");
if ($keys) {
$this->redis->del(...$keys);
}
$this->redis->del("tag:{$tag}");
}
}
Теги в Redis реализованы через Sets. Инвалидация по тегу — атомарная операция без блокировок файловой системы.
Стратегии кеширования
Модуль поддерживает несколько стратегий для разных типов данных:
- TTL-кеш — классический кеш с временем жизни. Для данных, меняющихся редко: настройки сайта, список регионов, параметры доставки
-
Event-invalidation — кеш сбрасывается при событии Битрикс. Повешивается на
OnAfterIBlockElementAdd,OnAfterIBlockElementUpdateи т.д. - Stale-while-revalidate — устаревший кеш отдаётся немедленно, а в фоне запускается перегенерация через агент. Устраняет «толпу» при промахе кеша
- Request-scoped — кеш на время одного HTTP-запроса (in-memory array). Избегает повторных запросов к БД в рамках одного запроса
Прогрев кеша
При сбросе кеша первый запрос всегда медленный — идёт в БД. При высокой нагрузке это приводит к spike. Агент прогрева решает проблему:
// Зарегистрированные warmup-задачи
$cache->registerWarmup('catalog_menu', function() {
return CIBlockElement::GetList(/* полный каталог */);
}, ['iblock_main_catalog'], 7200);
// Агент запускается раз в час и обновляет кеш до истечения TTL
\Vendor\Cache\WarmupAgent::run();
Мониторинг и статистика
Таблица b_vendor_cache_stat — для агрегированной статистики по ключам:
-
key_prefix,hits,misses,avg_ttl,last_hit_at
В административном интерфейсе:
- Hit rate по категориям ключей
- Топ «холодных» ключей (много промахов)
- Размер кеша по бэкендам
- Ручная инвалидация по тегу или ключу
- Лог последних операций инвалидации
Интеграция с компонентами Битрикс
Стандартные компоненты используют $APPLICATION->IncludeComponent() с параметром CACHE_TYPE. Модуль перехватывает этот механизм и перенаправляет в Redis:
// В init.php после подключения модуля
\Vendor\Cache\BitrixCacheBridge::install();
// → Переопределяет \Bitrix\Main\Data\Cache::createInstance()
// возвращая Redis-бэкенд вместо файлового
Bridge делает замену прозрачной — компоненты продолжают работать без изменений кода.
Сроки разработки
| Этап | Срок |
|---|---|
| Архитектура CacheManager, интерфейс бэкенда | 1 день |
| Redis-бэкенд с поддержкой тегов | 2 дня |
| Стратегии: stale-while-revalidate, request-scoped | 2 дня |
| Агент прогрева кеша | 1 день |
| Bridge для стандартных компонентов Битрикс | 1 день |
| Статистика, административный интерфейс | 2 дня |
| Тестирование под нагрузкой | 1 день |
Итого: 10 рабочих дней. Для проектов с кластером PHP-серверов — дополнительная настройка Redis Cluster или Sentinel: +1–2 дня.







