Персистентность: RDB и AOF

Redis живёт в памяти. Но что будет при перезагрузке сервера? Без персистентности — данные исчезнут. Разберём, как Redis сохраняет себя на диск.

«In-memory» не значит «обязательно временный». Redis умеет сохранять состояние на диск двумя способами, и выбор между ними — это компромисс между скоростью и долговечностью.

По умолчанию данные Redis — в RAM, и при сбое или рестарте они пропадут. Чтобы этого избежать, есть два механизма персистентности: RDB (снапшоты) и AOF (журнал команд). Их можно использовать вместе.

RDB: снапшоты

RDB периодически делает «фотографию» всего набора данных и пишет её в компактный бинарный файл (dump.rdb). Это быстро при загрузке и удобно для бэкапов, но между снапшотами можно потерять данные при сбое.

# В redis.conf: делать снапшот, если за 60с было 1000+ изменений
save 60 1000

# Вручную (в фоне, не блокируя)
BGSAVE

AOF: журнал команд

AOF (Append Only File) записывает каждую изменяющую команду в журнал. При рестарте Redis «проигрывает» журнал заново и восстанавливает состояние. Это надёжнее RDB, но файл больше и восстановление дольше.

# В redis.conf
appendonly yes
appendfsync everysec    # сбрасывать на диск раз в секунду

appendfsync: три режима

   Когда AOF сбрасывается на диск?

   always    -- после каждой команды.
                Максимальная надёжность, но медленно.
   everysec  -- раз в секунду (в фоне).
                Баланс: теряем максимум ~1 секунду. ДЕФОЛТ.
   no        -- решает ОС.
                Быстро, но при сбое потерь больше.

appendfsync everysec — золотая середина: высокая производительность при потере не более одной секунды записей в худшем случае.

Гибридный режим

Современная рекомендация для продакшена — RDB + AOF вместе. При старте Redis грузит компактный RDB-преамбл (быстро), а затем дописывает «хвост» из AOF (свежие команды). Так вы получаете и быстрый рестарт, и потерю максимум одной секунды данных.

   Восстановление в гибридном режиме

   Рестарт Redis
        |
        v
   [читаем RDB-снапшот] --> база состояния (быстро)
        |
        v
   [проигрываем хвост AOF] --> досвежаем до последней секунды
        |
        v
   данные восстановлены, потеря <= 1 сек

Как работает под капотом

RDB-снапшот делается через fork(): дочерний процесс пишет данные на диск, пока родитель продолжает обслуживать запросы (copy-on-write память). AOF при everysec копит команды в буфер и сбрасывает его fsync раз в секунду в фоновом потоке — поэтому записи остаются быстрыми. AOF со временем разрастается, поэтому Redis периодически делает rewrite: компактно переписывает журнал, оставляя минимум команд для воссоздания текущего состояния.

Частые ошибки

  • Считать Redis надёжным без настройки персистентности. По умолчанию при сбое возможна потеря данных.
  • appendfsync always в погоне за надёжностью. Резко роняет производительность; everysec обычно достаточно.
  • Хранить RDB/AOF на том же диске, что и всё остальное, без бэкапов. Потеря диска = потеря данных.

Best practices

  • Для данных, которые жаль терять, включайте AOF с appendfsync everysec + периодический RDB для бэкапов (гибрид).
  • Регулярно копируйте RDB-файлы в отдельное хранилище для disaster recovery.
  • Если Redis — чистый кэш и потеря не страшна, персистентность можно отключить ради скорости.

Итог: RDB — быстрые компактные снапшоты для бэкапов, AOF — надёжный журнал команд. appendfsync everysec теряет максимум секунду при высокой скорости. Гибридный режим (RDB + AOF) — рекомендация для продакшена: быстрый рестарт и минимальные потери.

Как выбрать конфигурацию под задачу

Выбор персистентности — это не «включить всё на максимум», а соответствие требованиям конкретного сервиса. Разберём типичные профили:

  • Чистый кэш, потеря не страшна. Персистентность можно вообще отключить ради максимальной скорости — при рестарте кэш просто прогреется заново из БД.
  • Кэш + важные данные. AOF с appendfsync everysec плюс периодический RDB для бэкапов. Потеря не более секунды, быстрый рестарт.
  • Redis как хранилище. AOF обязателен; RDB — для удобных бэкапов и disaster recovery. Возможно, appendfsync always для критичных данных, если производительность позволяет.

Важно понимать стоимость операций. RDB-снапшот через fork() на больших базах создаёт всплеск использования памяти из-за copy-on-write и нагружает диск — поэтому его планируют на периоды меньшей нагрузки. AOF без периодического rewrite разрастается и замедляет рестарт. Поэтому в продакшене обычно держат гибрид: AOF для долговечности «здесь и сейчас» и RDB-снапшоты для компактных бэкапов, которые регулярно копируют в отдельное хранилище. Так вы защищены и от сбоя процесса, и от потери самого диска.

Проверьте себя
1. Что гарантирует режим appendfsync everysec в AOF?
AНулевую потерю данных при любом сбое
BВысокую производительность при потере максимум около одной секунды записей в худшем случае
CСохранение только последнего снапшота
DЗапись на диск после каждой команды
2. В чём преимущество гибридного режима RDB + AOF при восстановлении?
AОн удваивает скорость всех команд
BRedis грузит компактный RDB-снапшот (быстрый старт), затем досвежает хвостом AOF — быстрый рестарт и потеря не более секунды
CОн полностью исключает любую запись на диск
DОн работает только с маленькими базами