Прямой ответ
Redis в локальном стеке поднимается одной командой и в роли кэша почти не требует настройки:
docker run -d --name redis-dev -p 6379:6379 --memory 512m redis:7-alpine
Два решения, которые нужно принять сразу: политика вытеснения (maxmemory + maxmemory-policy) — без неё Redis при упоре в лимит контейнера получит OOM-kill вместо корректного вытеснения старых ключей; и отношение к персистентности — для кэша её удобнее отключить (данные восстановимы), для очередей задач — наоборот, включить и хранить в volume. Холостой Redis потребляет 10–30 МБ; весь ваш кэш — это ровно те данные, что вы в него положили, плюс небольшой overhead.
Кэш: настройки, которые имеют смысл локально
docker exec redis-dev redis-cli CONFIG SET maxmemory 384mb
docker exec redis-dev redis-cli CONFIG SET maxmemory-policy allkeys-lru
Смысл политики: кэш обязан уметь забывать. allkeys-lru вытесняет давно неиспользуемые ключи — типовой выбор для кэша приложения; noeviction (дефолт) при переполнении начинает отвечать ошибками на запись — и локальное приложение «внезапно» падает там, где прод с настроенным LRU работал бы дальше. Локальный стенд затем и нужен, чтобы такие расхождения ловить до прода.
Практика разработки: ключи кэша снабжайте TTL всегда (SET key val EX 300) — вечные ключи превращают кэш в свалку; префиксы (app:cache:...) делают отладку читаемой. Смотреть, что живёт в кэше: redis-cli --bigkeys (тяжёлые ключи), SCAN (не KEYS * — он блокирует сервер; на локальном объёме не смертельно, но привычка плохая), INFO memory (used_memory_human — реальное потребление).
Очереди: противоположные требования
Когда Redis — брокер (RQ, Celery-redis, BullMQ), данные терять нельзя: включите AOF (appendonly yes) и держите каталог данных в volume. Политика вытеснения для инстанса очередей — строго noeviction: вытеснить элемент очереди = потерять задачу. Отсюда архитектурное правило, которое стоит воспроизвести и локально: кэш и очереди — разные инстансы Redis, даже в dev; compose-профиль с двумя сервисами (redis-cache, redis-queue) стоит 30 МБ памяти, но исключает класс багов «очистка кэша уронила задачи».
Персистентность в цифрах: RDB-снапшоты компактны и достаточны для кэша; AOF пишет каждую операцию — надёжнее для очередей, но на медленном диске добавляет задержки. Локально обе схемы недороги; volume для данных обязателен (bind mount из Windows, как и для PostgreSQL, тормозит — правило из статьи про Compose-стек).
Отладка и наблюдение
redis-cli покрывает 95% локальной диагностики:
redis-cli INFO clients # подключения: не течёт ли пул приложения
redis-cli INFO stats | grep -E "evicted|expired" # вытеснения и истечения
redis-cli SLOWLOG GET 10 # медленные команды
redis-cli MEMORY USAGE app:cache:user:42 # размер конкретного ключа
redis-cli MONITOR # живой поток команд (коротко: грузит сервер)
Типичные находки: evicted_keys растёт — кэш мал или TTL слишком длинный; connected_clients растёт монотонно — приложение не закрывает соединения пула; огромный ключ (MEMORY USAGE десятки МБ) — сериализуете в кэш целый объект вместо выборочных полей. GUI (Another Redis Desktop Manager, RedisInsight) удобен для осмотра структуры, но CLI быстрее входит в привычку и работает везде.
Чем заменить Redis локально, когда он избыточен
Не каждому стеку нужен отдельный Redis-контейнер: для кэша единственного инстанса приложения хватает in-process кэша (LRU в коде); для очередей фоновых задач в Django/Flask-приложениях малого размера — очереди в PostgreSQL (SKIP LOCKED) без нового сервиса; для сессий — подписанные cookie. Критерий простой: если Redis в проекте появился «потому что в tutorial был», оцените, что именно он даёт против встроенных механизмов вашей БД. Если же Redis в проде — локальная копия обязательна: разработка против эмуляций расхождение не ловит, а интеграционные тесты с настоящим Redis поднимаются через testcontainers — отдельный одноразовый инстанс на каждый прогон.
Ресурсы и бюджет стека
Redis экономичен: 30 МБ холостой, 256–512 МБ лимита хватает на очень крупный dev-кэш. В общем бюджете локального стека (приложение + PostgreSQL + Redis) из статьи про локальный PostgreSQL он — самый дешёвый сосед. Экономия нужна не по памяти, а по вниманию: каждый лишний сервис — это ещё один лог, ещё одна версия и ещё одна причина «локально не поднимается».
FAQ
Почему Redis в контейнере умер с OOMKilled?
Контейнерный лимит ниже maxmemory (или он не задан, и Redis рос до лимита). Правило: maxmemory ≈ 75% от --memory контейнера — запас нужен на overhead структуры данных.
Можно ли использовать один Redis для кэша и очередей в dev? Технически да, но политика вытеснения у ролей конфликтует (LRU против noeviction). Два контейнера — правильнее и почти бесплатно.
Нужен ли пароль на локальном Redis?
Если порт 6379 не проброшен в локальную сеть — минимально. В общей сети (офис, коворкинг) без пароля ваш Redis станет чужим майнером за часы: ставьте requirepass в любом compose, поднимаемом вне изолированного хоста.
Redis или Memcached для учебного проекта? Redis: структуры данных, персистентность, очереди — всё в одном сервисе. Memcached проще, но уже; в новых проектах почти всегда выбирают Redis.
Мини-сценарий: воспроизводимый кэш-баг
Показательный случай, ради которого локальный Redis настраивают «как прод». Приложение работает, затем «случайно» начинает отдавать устаревшие данные раз в несколько часов. Локальное воспроизведение: поднимаете Redis с тем же maxmemory, что в проде, наполняете кэш тестовыми ключами до вытеснения (redis-cli DEBUG POPULATE или цикл записи) и наблюдаете evicted_keys в INFO stats — если политика noeviction, получаете ошибки записи; если LRU — видите, какие ключи вытесняются первыми и почему приложение читает пустоту. Весь эксперимент занимает десять минут и не требует доступа к продакшену.
Та же техника работает для очередей: искусственно переполните очередь и проверьте поведение воркеров — обработка backpressure, повторные попытки, dead-letter. Локальный стенд с настоящими лимитами превращает «загадочные прод-инциденты» в воспроизводимые тесты; ровно для этого dev-стек и настраивают с продакшен-параметрами вместо «по умолчанию».
Как быстро посмотреть, что приложение реально кладёт в кэш? Короткий сеанс MONITOR покажет живой поток команд с ключами — обычно сразу видно и лишние записи, и ключи без TTL. Держите сеанс секунды: на активной нагрузке MONITOR сам создаёт заметную нагрузку на сервер.
Источники: документация Redis (config, memory optimization, persistence) — ссылки в шапке.