13-redis — Redis
☐ Опциональный. Быстрое хранилище «ключ-значение» в памяти: ставит Redis, привязывает его к localhost и защищает паролем.
Redis — сверхбыстрое хранилище данных в оперативной памяти (кэш, сессии, очереди, счётчики). Термины: bind — на каких сетевых адресах служба принимает подключения (localhost = только с этого же сервера); requirepass — пароль, который Redis требует у клиента перед выполнением команд; PING → PONG — простейшая проверка «жив ли сервер» (клиент шлёт PING, сервер отвечает PONG).
Зачем нужен
Redis держит данные в памяти и отдаёт их за микросекунды — идеален для кэша, пользовательских сессий, rate-limiting, лёгких очередей задач. Модуль ставит Redis из репозитория дистрибутива, сразу закрывает его на localhost и включает пароль, чтобы «из коробки» его нельзя было прочитать снаружи.
Когда включать и когда не нужен
- Включайте, если приложение кэширует ответы, хранит сессии вне процесса, использует очереди (Bull, Sidekiq, Celery), считает лимиты запросов.
- Не нужен, если проекту хватает памяти процесса, если кэш живёт в Docker-контейнере рядом с приложением или если очереди вы держите в RabbitMQ/Kafka.
Зависимости и требования
- Отдельных модулей-зависимостей нет.
- Debian/Ubuntu — пакет
redis-server; RHEL/SUSE/Arch — пакетredis(mitdev подставит правильное имя автоматически). - Права root.
- Модуль ставит
vm.overcommit_memory=1(иначе Redis предупреждает и фоновые сохранения через fork могут падать).
Что именно делает
Пошагово, функция module_install в modules/13-redis.sh:
- Самолечение dpkg.
redis_repair_statoverride: если прошлое неудачное удаление оставило «висячую» записьdpkg-statoverrideна пользователяredis, которого уже нет (это блокирует любые apt/dpkg-операции на всём сервере), пользователь пересоздаётся. - Ставит пакет
redis-serverи делает резервную копию/etc/redis/redis.conf. - Привязывает к localhost. Если
REDIS_BINDне задан — по умолчаниюbind 127.0.0.1;::1(IPv6-loopback) добавляется, только если он реально есть на интерфейсеlo. Причина осторожности — ниже. - Ставит пароль (
requirepass). Если пароль ещё не настроен — генерирует случайный, вписывает в конфиг и сохраняет в/root/.mitdev-credentials. Если пароль уже есть — не перетирает его (идемпотентность: повторный запуск не сбросит рабочий пароль). - Настраивает systemd-таймауты (
svc_set_timeouts) — убирает предупреждение Redis проTimeoutStartSec/TimeoutStopSec. - Включает overcommit памяти (
vm.overcommit_memory=1) — постоянно (файл/etc/sysctl.d/99-mitdev-redis.conf) и сразу. - Включает и перезапускает службу. Если Redis не поднялся — печатает последние строки его лога и завершается с ошибкой.
- Проверяет
PING → PONG(с паролем, если только что его задал). Нет ответа — установка неуспешна.
Файлы, службы и порты
| Путь / юнит / порт | Назначение | Права / примечание |
|---|---|---|
Служба redis-server (Debian) / redis (RHEL и др.) |
systemd-юнит Redis | mitdev redis status |
Порт 6379/tcp |
приём подключений | по умолчанию только 127.0.0.1 |
/etc/redis/redis.conf |
конфигурация (bind, requirepass) |
правится модулем, есть .mitdev-bak.* |
/var/lib/redis/ |
данные (dump.rdb) |
владелец redis |
/var/log/redis/redis-server.log (Debian) |
лог сервера | смотреть при сбое запуска |
/etc/sysctl.d/99-mitdev-redis.conf |
vm.overcommit_memory=1 |
системный параметр |
/root/.mitdev-credentials |
пароль (requirepass) |
0600, только root |
Учётные данные
Пароль Redis (requirepass) хранится в /root/.mitdev-credentials (0600, только root). Посмотреть:
sudo grep '^redis:' /root/.mitdev-credentials
Пример:
redis: password=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
Если при установке пароль не был настроен, mitdev сгенерировал случайный и записал его сюда же. Если Redis был установлен ранее и уже имел requirepass, mitdev его не менял — актуальный пароль ищите в самом /etc/redis/redis.conf (строка requirepass …).
Настройка
| Переменная | Значения | По умолчанию | Влияние | Когда менять |
|---|---|---|---|---|
REDIS_BIND |
список адресов через пробел, например 127.0.0.1 |
пусто (автоопределение) | на каких адресах Redis слушает | почти никогда вручную — см. предупреждение ниже |
Почему REDIS_BIND пуст по умолчанию. При пустом значении модуль сам подставляет 127.0.0.1 и добавляет ::1 только когда IPv6-loopback реально присутствует. Это сделано специально: синтаксис необязательной привязки -::1 понимают только Redis 6.2+/7, а на Ubuntu 22.04 идёт Redis 6.0.x, который на нём падает с exit(1) («Cannot assign requested address»), если ::1 нет на хосте. Поэтому не прописывайте ::1 руками, если не уверены в версии Redis — доверьте автоопределению.
Как переопределить настройки
- Экспорт переменной перед установкой (обычно не требуется):
export REDIS_BIND="127.0.0.1" sudo -E ./install.sh - Правка дефолта в
config/defaults.conf(REDIS_BIND=""). - Чтобы открыть Redis другому серверу — не меняйте bind вручную на
0.0.0.0, используйтеmitdev net bind redis private(см. «Как подключиться»).
Как подключиться
Из приложения на этом же сервере — строка подключения через localhost с паролем:
redis://:<password>@127.0.0.1:6379
Например в .env:
REDIS_URL=redis://:[email protected]:6379
(двоеточие перед паролем не опечатка — у Redis по умолчанию нет имени пользователя, только пароль).
Из командной строки (redis-cli):
redis-cli -a 'ПАРОЛЬ' ping # ожидаемо: PONG
redis-cli -a 'ПАРОЛЬ' --no-auth-warning info server
Флаг --no-auth-warning убирает предупреждение о пароле в аргументах.
С другого сервера — БЕЗОПАСНО. По умолчанию 6379 доступен только локально, и это правильно: Redis без TLS нельзя выставлять в интернет. Правильный путь — приватная сеть:
- Соберите mesh-сеть:
mitdev net create/join(см. MESH.md). - Привяжите Redis к приватному интерфейсу:
sudo mitdev net bind redis private— служба будет слушать приватный IP +127.0.0.1, но не публичный. - Приложение с соседнего сервера подключается по приватному IP с тем же паролем.
Никогда не делайте bind 0.0.0.0 на публичном сервере — это открывает Redis всему интернету.
Проверка, что всё работает
Проверка модуля (module_verify): служба активна. Вручную:
mitdev redis status
Ожидаемо: блок Redis с role:master; если Sentinel не настроен — строка «redis-sentinel не запущен» (это нормально для одиночного Redis).
redis-cli -a "$(sudo grep '^redis: password' /root/.mitdev-credentials | cut -d= -f2)" ping
Ожидаемо: PONG.
mitdev doctor --deep
В функциональных пробах: Redis — PONG.
Типовые задачи
Записать и прочитать ключ:
redis-cli -a 'ПАРОЛЬ' --no-auth-warning set greeting "hello"
redis-cli -a 'ПАРОЛЬ' --no-auth-warning get greeting # → "hello"
Сменить пароль Redis:
sudo sed -i -E 's/^\s*requirepass .*/requirepass НОВЫЙ-ПАРОЛЬ/' /etc/redis/redis.conf
sudo systemctl restart redis-server
Затем обновите пароль в .env приложения и в /root/.mitdev-credentials.
Очистить кэш (удалить все ключи текущей БД / всех БД):
redis-cli -a 'ПАРОЛЬ' --no-auth-warning flushdb # только текущая логическая БД
redis-cli -a 'ПАРОЛЬ' --no-auth-warning flushall # все базы Redis
Посмотреть активные соединения и клиентов:
redis-cli -a 'ПАРОЛЬ' --no-auth-warning info clients
redis-cli -a 'ПАРОЛЬ' --no-auth-warning client list
Использование памяти и статистика попаданий в кэш:
redis-cli -a 'ПАРОЛЬ' --no-auth-warning info memory
redis-cli -a 'ПАРОЛЬ' --no-auth-warning info stats | grep keyspace
Резервная копия данных (снимок dump.rdb):
redis-cli -a 'ПАРОЛЬ' --no-auth-warning save
sudo cp /var/lib/redis/dump.rdb /root/redis-$(date +%F).rdb
Общий бэкап сервера (mitdev backup) тоже включает dump.rdb.
Сколько всего ключей:
redis-cli -a 'ПАРОЛЬ' --no-auth-warning dbsize
Масштабирование и отказоустойчивость
Одиночный Redis — точка отказа. Для HA mitdev использует Redis Sentinel (набор процессов-наблюдателей, которые следят за master, выбирают нового при отказе и сообщают клиентам актуальный адрес):
sudo mitdev redis cluster-init [имя] [кворум] [ip...]— на первом сервере: делает узел master, генерирует/берётrequirepass, привязывает Redis к своему IP, поднимает Sentinel (порт26379) и открывает6379/26379для перечисленных узлов.sudo mitdev redis token— токен для реплик (адрес master, порт, пароль, кворум, список узлов).sudo mitdev redis join <токен>— на реплике: проверяет доступность master, затемreplicaofmaster + Sentinel на тот же master.sudo mitdev redis allow <ip>(на каждом узле),sudo mitdev redis check(проверка связности),sudo mitdev redis promote(ручной failover).
Обязательное условие: все узлы видят друг друга на 6379
Sentinel находит реплики, разбирая INFO на master, и сам ходит к каждой из них на 6379. Если узел не может достучаться до соседа на этом порту, он объявляет его недоступным (+sdown) — даже когда сосед жив. Sentinel'ы расходятся во мнении, кто master, и начинают перевыбирать его друг против друга. В журнале это выглядит как непрерывная череда +switch-master и +failover-end-for-timeout, а в кластере оказывается два master сразу.
Поэтому 6379 и 26379 должны быть открыты между всеми узлами в обе стороны — в UFW и в файрволе провайдера. cluster-init и join делают это для известных им узлов; для добавленных позже выполните sudo mitdev redis allow <ip> на каждом узле. После сборки обязательно прогоните на всех узлах:
sudo mitdev redis check
Пока эта проверка не проходит везде, авто-failover работать не будет. Приватная сеть (mitdev net) не обязательна, но желательна: она избавляет от необходимости открывать порты в публичный интернет.
Подробности — COMMANDS.md (раздел «Отказоустойчивый Redis») и HA.md.
Частые ошибки
Симптом: NOAUTH Authentication required при обращении к Redis.
Причина: не передан пароль.
Решение: используйте redis-cli -a 'ПАРОЛЬ' или укажите пароль в строке подключения приложения.
Симптом: Redis не стартует, в логе Cannot assign requested address.
Причина: в bind прописан ::1, а IPv6-loopback на хосте отсутствует (частая беда Redis 6.0.x на Ubuntu 22.04).
Решение: уберите ::1 из строки bind в /etc/redis/redis.conf, оставьте bind 127.0.0.1, перезапустите; не задавайте REDIS_BIND вручную с ::1.
Симптом: предупреждение overcommit_memory is set to 0 и падающие фоновые сохранения.
Причина: параметр ядра не применился.
Решение: sudo sysctl -w vm.overcommit_memory=1 (модуль обычно ставит это сам через /etc/sysctl.d/99-mitdev-redis.conf).
Симптом: любые apt/dpkg на сервере падают с «unknown system user 'redis' in statoverride file».
Причина: висячая запись dpkg-statoverride после неудачного удаления.
Решение: повторный запуск модуля Redis лечит это автоматически (redis_repair_statoverride); либо вручную пересоздайте пользователя redis.
Симптом: приложение с соседнего сервера не видит Redis.
Причина: Redis слушает только localhost.
Решение: соберите приватную сеть и выполните sudo mitdev net bind redis private — не открывайте порт наружу.
Симптом: после отказа одного сервера мастер меняется каждые несколько секунд; в journalctl -u redis-sentinel бесконечная череда +switch-master и +failover-end-for-timeout; два узла одновременно в роли master.
Причина: узлы не видят друг друга на 6379, поэтому каждый Sentinel объявляет чужого мастера мёртвым и повышает своего.
Решение: остановите Sentinel на всех узлах (sudo systemctl stop redis-sentinel), откройте 6379/26379 между узлами, добейтесь, чтобы sudo mitdev redis check проходил везде, затем соберите кластер заново: mitdev redis token на уцелевшем мастере и mitdev redis join <токен> на остальных.
Симптом: mitdev redis status пишет «РАСХОЖДЕНИЕ: локальный redis — master, а Sentinel считает мастером …».
Причина: узел не переключился в реплику после failover и живёт отдельным мастером (split-brain).
Решение: снимите с него дамп (redis-cli -a <пароль> --rdb /root/backup.rdb), затем mitdev redis join <токен> с действующего мастера — данные узла будут затёрты полной синхронизацией.
Откат и удаление
- Автоматический откат (
module_rollback) при сбое установки: отключает службу, удаляет пакет, чистит записиdpkg-statoverride. - Снять только HA-оверлей, оставив Redis и данные:
После этого узел — обычный автономный Redis; кластер можно собрать заново с нуля.sudo mitdev redis cluster-remove # стоп Sentinel, его конфиг, правила UFW, replicaof - Ручное удаление:
Безsudo mitdev remove redis # снести пакет, ДАННЫЕ и конфиг СОХРАНИТЬ sudo mitdev remove redis --purge # снести всё, включая /var/lib/redis и /etc/redis--purgeданные (/var/lib/redis) и конфигурация сохраняются. С--purgeони удаляются безвозвратно. В обоих случаях HA-оверлей снимается всегда: иначе оставшийсяredis-sentinelбудет писать+sdownв журнал, а уцелевшийsentinel.confили строкаreplicaofпри переустановке молча вернут узел в несуществующий кластер.
См. также
- COMMANDS.md — команды
mitdev redis …(Sentinel: cluster-init, token, join, promote) - HA.md — отказоустойчивость и Sentinel
- MESH.md — приватная сеть и
mitdev net bind - SECURITY.md — безопасность и учётные данные