AOF (Append Only File) дописывает каждую изменяющую команду в лог; при старте Redis переигрывает журнал и восстанавливает состояние. Это механизм для «потеряем не больше секунды».
Настройка и fsync-политики
appendonly yes
appendfilename "appendonly.aof"
appendfsync always # fsync после КАЖДОЙ команды: максимум сохранности, минимум скорости
appendfsync everysec # fsync раз в секунду фоновым потоком — РЕКОМЕНДУЕМЫЙ компромисс
appendfsync no # решает ОС (обычно ~30с буферов): быстро, но непредсказуемо
| Политика | RPO (потеря при аварии) | Цена |
|---|---|---|
| always | ~0 (команда подтверждена после записи на диск) | латентность записи = диск; X10–100 на HDD |
| everysec | ≤ 1 сек | почти незаметна |
| no | до десятков секунд, недетерминировано | минимальна |
При everysec, если fsync задержался (медленный диск), Redis по умолчанию
останавливает запись (no-appendfsync-on-rewrite no) вместо бесконечного
накопления — следите за aof_delayed_fsync в INFO persistence.
Rewrite: журнал не должен расти вечно
AOF содержит каждую команду — включая сотни инкрементов одного счётчика. Rewrite переписывает журнал в «минимальное» представление текущего состояния (SET вместо тысяч команд).
- Механика как у BGSAVE: fork + ребёнок пишет новый файл; родитель копит новые команды в буфер и дописывает в конец готового файла;
- Триггеры:
auto-aof-rewrite-percentage 100(журнал вырос на 100% от последнего rewrite) иauto-aof-rewrite-min-size 64mb; - Ручной:
BGREWRITEAOF; - Замечание для отчётности: SET снимает TTL, но в AOF само истечение пишется как DEL/UNLINK при активной вычистке — восстановленный датасет совпадает с моментом снимка.
Multi-part AOF (Redis 7+)
С 7-й версии AOF — это «базовый» файл (результат последнего rewrite) + инкрементальные файлы + манифест. Плюсы: быстрый рестарт (база загружается без переигрывания всей истории), устойчивость к частичной порче, возможность отключить rewrite во время работы.
Целостность и починка
# Проверка целостности файла
redis-check-aof appendonly.aof
# Усечение оборванного хвоста (частый случай после аварии диска)
redis-check-aof --fix appendonly.aof
⚠️ Рестарт с AOF переигрывает журнал: восстановление большого датасета заметно медленнее, чем загрузка RDB. Это ещё одна причина держать обе технологии: RDB для скорости рестарта, AOF для минимума потерь (Redis грузит AOF, если он есть — он новее).
RDB vs AOF — итог
| Сценарий | Рекомендация |
|---|---|
| Чистый кеш | RDB (или ничего) |
| Смешанное, потеря ≤1с терпима | RDB + AOF everysec (стандарт индустрии) |
| Хранилище, потеря ≤1с недопустима | AOF always + реплики + бэкапы; честно считайте цену латентности |
Практика
- Включите AOF everysec, запишите 1000 ключей,
kill -9процесса сразу после последней записи, поднимите: посчитайте фактическую потерю. - Повторите то же с
appendfsync alwaysи сравните потери и throughput (redis-benchmark -t set -P 1). - Сделайте
BGREWRITEAOFна журнале с миллионом INCR одного счётчика — сравните размер файла до/после. - Найдите в
INFO persistence: aof_enabled, aof_last_bgrewrite_status, aof_current_size, aof_delayed_fsync.
Мини-квиз
1. Сколько данных потеряете на everysec при отключении питания? — До ~1 секунды подтверждённых записей.
2. Зачем rewrite, если команды и так применяются? — Компактность и скорость восстановления: журнал содержит историю, а не состояние.
3. Почему Redis при старте предпочитает AOF? — Он обычно более полный (новее), чем последний RDB-снимок.