We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

К списку статей

Многослойный кэш в высоконагруженных проектах на Symfony и Django

28 янв 2026 в 09:30 Усачёв Денис Евгеньевич

В современных веб‑приложениях, где количество запросов может достигать миллионов в секунду, простого кеша недостаточно. Нужно комбинировать несколько уровней кеширования, каждый из которых решает свою задачу: быстрый in‑memory кеш, HTTP‑кеш на границе сети и кеш запросов к базе данных. В статье рассматриваются три ключевых слоя – Redis, Varnish и Doctrine Result Cache – и их интеграция в Symfony и Django.

Общая архитектура многослойного кеша

Схема выглядит следующим образом:

  • Varnish – кеширует готовый HTTP‑ответ и находится перед веб‑сервером (nginx/apache). Он обслуживает запросы без обращения к приложению.
  • Redis – быстрый key‑value store, используется для кеша бизнес‑логики, сессий, токенов и результатов тяжёлых запросов.
  • Doctrine Result Cache (в Symfony) – кеширует результаты SQL‑запросов, снижая нагрузку на СУБД.

Каждый слой имеет свои TTL, правила инвалидации и стратегии обновления.

Redis – быстрый кеш в памяти

Redis идеален для:

  • Кеширования результатов тяжёлых вычислений и API‑запросов.
  • Хранения сессий и токенов аутентификации.
  • Выполнения атомарных операций (counters, locks).

Пример конфигурации Redis в Symfony (services.yaml):

services:
    RedisClient:
        class: Redis
        calls:
            - [connect, ['%env(REDIS_HOST)%', '%env(int:REDIS_PORT)%']]
            - [auth, ['%env(REDIS_PASSWORD)%']]
        public: true

В Django подключение выглядит так:

# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': f"redis://{os.getenv('REDIS_HOST')}:{os.getenv('REDIS_PORT')}/1",
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'PASSWORD': os.getenv('REDIS_PASSWORD'),
        }
    }
}

Varnish – HTTP‑кеш на границе сети

Varnish принимает запросы до того, как они достигнут PHP‑процесса. Он хранит готовый HTML (или JSON) и отдает его без выполнения кода приложения. Основные преимущества:

  • Снижение нагрузки на приложение и базу данных.
  • Масштабируемость за счёт горизонтального добавления узлов Varnish.
  • Гибкое управление TTL и правилами кеширования через VCL.

Пример простого VCL‑файла для Symfony‑приложения:

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080"; # порт, где работает PHP‑FPM
}

sub vcl_recv {
    if (req.url ~ "^/api/") {
        return (hash);
    }
    # Пропуск кеша для авторизованных пользователей
    if (req.http.Cookie ~ "session=" ) {
        return (pass);
    }
    return (hash);
}

sub vcl_backend_response {
    if (beresp.ttl <= 0s || beresp.http.Set-Cookie) {
        set beresp.ttl = 0s;
        set beresp.uncacheable = true;
        return (deliver);
    }
    set beresp.ttl = 10m; # 10 минут кеша для публичных страниц
    set beresp.grace = 1h;
}

Doctrine Result Cache (Symfony)

Doctrine умеет кешировать результат отдельных SQL‑запросов. Это особенно полезно для тяжёлых запросов, которые часто повторяются, но меняются редко.

Настройка кеша в doctrine.yaml:

# config/packages/doctrine.yaml
doctrine:
    orm:
        metadata_cache_driver: redis
        query_cache_driver: redis
        result_cache_driver:
            type: service
            id: doctrine.result_cache_provider

services:
    doctrine.result_cache_provider:
        class: Doctrine\ORM\Cache\ResultCacheProvider
        factory: ['@doctrine.orm.default_entity_manager', getResultCache]
        arguments: ['@RedisClient']

Использование в репозитории:

public function findPopularPosts(int $limit = 10): array
{
    $qb = $this->createQueryBuilder('p')
        ->where('p.views > :minViews')
        ->setParameter('minViews', 1000)
        ->orderBy('p.views', 'DESC')
        ->setMaxResults($limit);

    return $qb->getQuery()
        ->useResultCache(true, 3600) // кеш на 1 час
        ->getResult();
}

Кеширование в Django – слой запросов

В Django аналогом Result Cache выступает кеширование запросов к ORM через django.core.cache или сторонние библиотеки, такие как django-cacheops. Пример с cacheops:

# settings.py
CACHEOPS = {
    'app_label.model_name': {'cache': 'default', 'timeout': 6015},  # 15 минут
    '.*': {'cache': 'default', 'timeout': 60},  # По умолчанию 1 минута
}

INSTALLED_APPS += ['cacheops']

Использование в коде:

from cacheops import cached_as

@cached_as(Post, timeout=300)
def get_top_posts(limit=5):
    return Post.objects.filter(views__gt=1000).order_by('-views')[:limit]

Лучшие практики построения многослойного кеша

  1. Разделяй уровни по сроку жизни: Varnish – секунды‑минуты, Redis – минуты‑часы, Result Cache – часы‑дни.
  2. Не кешируй персональные данные: проверяй наличие cookies/Authorization‑header и делай pass в Varnish.
  3. Инвалидация: используйте события доменной модели (post‑persist, post‑update) для сброса Redis/Result Cache.
  4. Мониторинг: собирайте метрики (hit/miss) из Varnish (varnishstat), Redis (INFO), Doctrine (doctrine:cache:pool:list).
  5. Тестирование нагрузки: при помощи k6 или locust проверяйте, как каждый слой реагирует на рост запросов.

Отладка и мониторинг

Для Symfony:

# Проверка состояния кеша Doctrine
php bin/console doctrine:cache:clear-metadata
php bin/console doctrine:cache:clear-query
php bin/console doctrine:cache:clear-result

Для Django:

# Очистка кеша Redis
python manage.py shell -c "from django.core.cache import cache; cache.clear()"

Varnish предоставляет готовые инструменты:

# Статистика Varnish
varnishstat -1
# Показать текущий кэшированный объект
varnishlog -c -g request -i RxHeader -I X-Cache

Заключение

Многослойный кеш – это проверенный путь к масштабируемости высоконагруженных сервисов. Комбинация Varnish, Redis и кеша запросов позволяет снизить время отклика от секунд до миллисекунд, уменьшить нагрузку на базу данных и обеспечить устойчивость при пиковых нагрузках. Правильное проектирование TTL, инвалидации и мониторинга гарантирует, что кеш будет работать в пользу бизнеса, а не станет источником ошибок.

Услуги RybinskLab

Компания RybinskLab предлагает комплексную разработку и оптимизацию высоконагруженных веб‑приложений на Symfony и Django. Мы поможем спроектировать многослойную кеш‑стратегию, настроить Varnish, Redis и Result Cache, а также обеспечить мониторинг и поддержку в продакшн‑среде.

* Материал подготовлен с использованием ИИ-ассистента, проверен и отредактирован экспертом RybinskLab.

Поделиться материалом:

Нужна сложная разработка?

Усачёв Денис Евгеньевич — проектирование архитектуры, бэкенд на PHP/Python, интеграции API и базы данных.

Обсудить проект