MAATRIX / Блог / Redis: теряет данные после перезапуска — причины и решение

Redis: теряет данные после перезапуска — причины и решение

Redis: теряет данные после перезапуска — причины и решение

MAATRIX

Перезагрузили сервер или сервис — и база пуста, все ключи исчезли. Когда Redis теряет данные после перезапуска, это почти всегда не баг, а следствие настроек: по умолчанию Redis держит данные в памяти, а сохранение на диск нужно правильно включить и проверить. Разберём, как устроена персистентность, почему она может молча не работать и как настроить Redis так, чтобы данные переживали любой рестарт.

Обсудить статью, задать вопрос или начать новую тему

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

Перейти в сообщество →

Почему Redis вообще теряет данные

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

За сохранение на диск отвечают два механизма: RDB (снимки всей базы в определённые моменты) и AOF (журнал всех изменяющих команд). Они работают независимо и могут быть включены по отдельности или вместе. Прежде чем что-то чинить, определите, что у вас включено сейчас, и хотите ли вы вообще персистентности — или Redis у вас как кэш, где потеря данных при рестарте нормальна. От ответа зависит вся дальнейшая настройка.

Важно понимать разницу в способе остановки. Если Redis завершается штатно, командой SHUTDOWN или корректным сигналом от systemd, он по умолчанию успевает сохранить снимок на диск даже без строгих правил save. А вот при жёстком убийстве процесса, падении по OOM или внезапном отключении питания несохранённая часть памяти теряется безвозвратно. Поэтому «теряет данные после перезапуска» и «теряет данные после падения» — не одно и то же, и настраивать защиту нужно с расчётом на худший сценарий, а не на аккуратную перезагрузку.

Проверяем текущие настройки персистентности

Сначала выясните фактическое состояние, а не то, что написано в конфиге на диске — рабочие параметры могли переопределить на лету.

redis-cli CONFIG GET save
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET dir
redis-cli INFO persistence

Пустое значение save («») и appendonly no означают, что персистентность полностью выключена — Redis работает как чистый кэш и данные при рестарте не сохраняет. Если так и задумано (кэш перед базой), терять нечего, это нормально. Если же Redis у вас — хранилище, надо включать сохранение. В выводе INFO persistence смотрите на rdb_last_save_time, rdb_last_bgsave_status и aof_last_write_status: значение err вместо ok сразу указывает, что сохранение падает — и это отдельная проблема, разобранная ниже.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под базы данных

Включаем RDB-снимки

RDB создаёт бинарный снимок всей базы по расписанию: сохранить, если за N секунд изменилось M ключей. Это компактно и быстро восстанавливается, но между снимками данные под риском — при внезапном падении потеряется всё, что накопилось после последнего снимка.

В redis.conf задайте правила и путь:

save 900 1
save 300 10
save 60 10000
dir /var/lib/redis
dbfilename dump.rdb

Эти три строки означают: сохранять снимок, если за 900 секунд был хотя бы 1 изменённый ключ, за 300 секунд — 10, за 60 секунд — 10000. Чем активнее база, тем чаще снимки. После правки перезагрузите Redis и проверьте, что файл dump.rdb реально создаётся в каталоге dir. Форсировать снимок вручную для проверки:

redis-cli BGSAVE
ls -l /var/lib/redis/dump.rdb

Если после BGSAVE файл появился и обновил дату — RDB работает. Помните про компромисс: RDB не гарантирует нулевой потери, между снимками окно уязвимости. Для строгой сохранности нужен AOF.

Включаем AOF для надёжности

AOF (append-only file) пишет каждую изменяющую команду в журнал. При перезапуске Redis проигрывает журнал и восстанавливает состояние вплоть до последней записи. Это надёжнее RDB — потеря данных минимальна, обычно не больше секунды работы.

appendonly yes
appendfsync everysec
dir /var/lib/redis
appendfilename "appendonly.aof"

Параметр appendfsync everysec — золотая середина: журнал сбрасывается на диск раз в секунду, что даёт хороший баланс скорости и надёжности. Значение always надёжнее (сброс после каждой команды), но заметно медленнее; no быстрее, но отдаёт решение о сбросе операционной системе, и при падении потери больше. Для большинства хранилищ everysec оптимален. Включив AOF на живой базе, инициируйте перезапись, чтобы журнал сформировался:

redis-cli CONFIG SET appendonly yes
redis-cli BGREWRITEAOF
redis-cli INFO persistence | grep aof

Лучшая практика — держать включёнными оба механизма: AOF для восстановления с минимальной потерей, RDB как быстрый резервный снимок. Так вы застрахованы с двух сторон.

Права на каталог: тихая причина потери

Персистентность включена, но данные всё равно исчезают — частая причина в том, что Redis не может писать в свой каталог. Процесс запущен от пользователя redis, а каталог dir принадлежит root или защищён — сохранение молча падает, а вы об этом узнаёте только после рестарта.

redis-cli CONFIG GET dir
ls -ld /var/lib/redis
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|aof_last_write_status'

Если rdb_last_bgsave_status:err — Redis пытался сохранить и не смог. Проверьте владельца и права каталога, исправьте:

chown redis:redis /var/lib/redis
chmod 750 /var/lib/redis

Ещё одна ловушка — dir указывает на каталог, которого нет, или на раздел, где кончилось место. Redis не может создать файл снимка, и данные не сохраняются. Проверьте свободное место df -h и существование пути. На системах с SELinux добавьте корректный контекст, иначе запись блокируется даже при верных Unix-правах.

Разделяем: Redis как кэш или как хранилище

Прежде чем городить персистентность, честно ответьте: что для вас Redis? Если это кэш перед основной базой (сессии, временные результаты, счётчики, которые не жалко), потеря при рестарте — не проблема, а норма, и включать сохранение не нужно; оно только замедлит и займёт диск. Если же Redis — единственное место, где живут данные (очереди задач, важное состояние), персистентность обязательна, и лучше с AOF.

Многие проблемы «теряет данные» на самом деле — архитектурная путаница: Redis используют как надёжное хранилище, но настраивают как кэш. Определитесь с ролью. Для роли хранилища, помимо персистентности, продумайте резервные копии: настроенный AOF защищает от рестарта, но не от повреждения файла или потери диска. Регулярно копируйте dump.rdb и AOF на отдельное хранилище. Для по-настоящему критичных данных рассмотрите репликацию на второй сервер — тогда даже полный отказ узла не приведёт к потере.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под базы данных

Обсудить статью, задать вопрос или начать новую тему

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

Перейти в сообщество →

Частые вопросы

Почему Redis теряет все ключи после перезагрузки?

По умолчанию Redis хранит данные только в памяти. Если не включены RDB-снимки или AOF-журнал, при остановке процесса память очищается и данные исчезают. Включите персистентность и проверьте, что сохранение реально проходит.

Что надёжнее — RDB или AOF?

AOF надёжнее: он пишет каждую команду и восстанавливает базу с потерей не больше секунды. RDB делает снимки по расписанию, между которыми данные под риском. Лучшая практика — держать оба включёнными одновременно.

Персистентность включена, но данные всё равно пропадают. Почему?

Скорее всего, Redis не может писать в свой каталог: неверные права на dir, нехватка места или запрет SELinux. Проверьте INFO persistence — статус err означает, что сохранение падает. Исправьте владельца каталога и свободное место.

Нужна ли персистентность, если Redis используется как кэш?

Нет. Для кэша перед основной базой потеря данных при рестарте нормальна, и сохранение только замедлит работу. Персистентность нужна, когда Redis — единственное место хранения важных данных.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.