English translation is not available yet. Showing Russian content.
Настроить Redis с persistent storage (AOF + RDB)
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить Redis с persistent storage (AOF + RDB)
1. Цель задачи
Научиться конфигурировать Redis для надёжного хранения данных на диске с использованием комбинации механизмов RDB (snapshot) и AOF (append-only file). Освоить настройку параметров персистентности, провести тестирование восстановления после симулированного краша и добиться потери данных не более 1 секунды. В результате будет создана конфигурация Redis, готовая к промышленной эксплуатации с гарантированной долговечностью данных.
Ключевой результат Рабочий Redis-инстанс с включёнными AOF (everysec) и RDB (каждые 5 минут, если есть хотя бы 1 изменение), настроенный и протестированный на восстановление после убийства процесса (kill -9). Максимальная потеря данных — менее 1 секунды.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Redis (6.x или новее) | Установить через пакетный менеджер (apt, brew, choco) или официальный образ Docker redis:7 |
| Клиент для Redis | redis-cli (идёт в комплекте) или библиотека redis-py |
| Тестовые данные | Сгенерировать скриптом: redis-benchmark или собственный Python-скрипт, вставляющий 100 000+ ключей |
| Тестовый скрипт для краша | Bash-скрипт, который пишет данные, убивает процесс redis-server, затем перезапускает и проверяет количество потерянных ключей |
| Логи Redis | /var/log/redis/redis-server.log (зависит от ОС) |
| Инструмент мониторинга (опционально) | redis-cli INFO, redis-cli --stat |
Если нет реального инстанса — симулируем локально:
- Установите Docker Desktop или Podman.
- Запустите контейнер: docker run --name redis-persist -d redis:7 redis-server --save "" --appendonly yes
- Выполняйте все операции внутри контейнера (используя docker exec -it redis-persist redis-cli).
- Для убийства процесса: docker kill redis-persist (или docker stop --time=0 для резкого останова).
- После перезапуска проверьте данные через новый контейнер, смонтировав volume для данных.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Сервер кэширования | Redis (7+) | Хранение данных в памяти с персистентностью |
| Персистентность | RDB (dump.rdb), AOF (appendonly.aof) | Сохранение данных на диск |
| Клиент | redis-cli, Python redis-py | Взаимодействие с Redis, генерация нагрузки |
| Тестирование | Bash-скрипты, redis-benchmark, kill -9 | Проверка восстановления после краша |
| Конфигурация | redis.conf | Определение параметров AOF/RDB |
| Мониторинг | redis-cli INFO persistence | Состояние персистентности, размер AOF, время последнего RDB |
| Логирование | /var/log/redis/redis.log | Анализ загрузки AOF и RDB при старте |
4. Этапы выполнения
Этап 1: Подготовка окружения и запуск Redis с базовой конфигурацией (30 минут)
Действия
- Установите Redis (локально или Docker):
docker run --name redis-persist -p 6379:6379 -d redis:7 redis-server - Подключитесь к инстансу через redis-cli и выполните
PING— убедитесь, что работает. - Создайте директорию для конфигурации:
mkdir -p ~/redis-persist - Скопируйте дефолтный конфиг из контейнера (или скачайте с GitHub): docker cp redis-persist:/usr/local/etc/redis/redis.conf ~/redis-persist/redis.conf
- Временно отключите персистентность: в redis.conf закомментируйте все строки
saveи установитеappendonly no. - Перезапустите контейнер с монтированием конфига и отдельного volume для данных:
docker run --name redis-persist -v ~/redis-persist/redis.conf:/usr/local/etc/redis/redis.conf -v ~/redis-persist/data:/data -p 6379:6379 -d redis:7 redis-server /usr/local/etc/redis/redis.conf - Убедитесь, что Redis работает без персистентности: redis-cli INFO persistence — все поля должны быть нулевыми.
Ожидаемый результат этапа Запущен Redis без персистентности, готовый к настройке RDB и AOF. Данные не сохраняются на диск.
Этап 2: Настройка RDB (snapshot) (45 минут)
Действия
- В файле redis.conf раскомментируйте строки сохранения:
save 900 1 save 300 10 save 60 10000save 900 1— если изменился хотя бы 1 ключ за 15 минут, делаем snapshot.save 300 10— 10 изменений за 5 минут.save 60 10000— 10000 изменений за 1 минуту.
- Установите параметры RDB:
dbfilename dump.rdb dir /data rdbcompression yes rdbchecksum yes - Включите AOF параллельно? (Нет, пока оставляем
appendonly no). - Перезапустите контейнер (или выполните CONFIG REWRITE и CONFIG SET):
docker restart redis-persist - Проверьте, что RDB создаётся:
- Запишите 10000 ключей: for i in $(seq 1 10000); do redis-cli SET "key:$i" "value:$i"; done
- Подождите 60 секунд (условие
save 60 10000). - Проверьте файл: docker exec redis-persist ls -la /data/dump.rdb.
- Убедитесь через INFO persistence:
rdb_last_save_timeдолжен обновиться.
- Симулируйте мягкий краш: docker stop redis-persist (нормальное завершение — Redis вызовет
SAVEперед выходом, если включена опцияstop-writes-on-bgsave-error no). Затем запустите снова и проверьте, что данные восстановлены:docker start redis-persist redis-cli GET "key:1" # должен вернуть "value:1" redis-cli DBSIZE # близко к 10000
Ожидаемый результат этапа Redis работает с включённым RDB. После штатного останова данные восстанавливаются. Потеря данных при нештатном краше (kill -9) потенциально может достигать 15 минут (максимальное время между snapshot).
Этап 3: Включение AOF и настройка appendfsync everysec (45 минут)
Действия
- Отредактируйте redis.conf — включите AOF:
appendonly yes appendfsync everysec auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb - Параметр appendfsync everysec обеспечивает синхронизацию AOF каждую секунду в фоновом потоке. Это даёт гарантию потери не более 1 секунды данных (или 0 при наличии
always, но с большим снижением производительности). - Оставьте RDB включённым (рекомендуется гибридный режим). Redis 7+ при aof-use-rdb-preamble yes (по умолчанию) будет начинать AOF с RDB-снапшота.
- Перезапустите Redis: docker restart redis-persist.
- Проверьте статус AOF:
redis-cli INFO persistence # aof_enabled:1 # aof_current_size: (должен расти после записи) - Тест на потерю данных < 1 секунды:
- Напишите уникальные ключи с высокой частотой в течение 5 минут (например, Python-скрипт, который каждые 10 мс вставляет новый ключ).
- Зафиксируйте точное количество записанных ключей.
- Выполните жёсткое убийство процесса: docker kill --signal=KILL redis-persist (эквивалент kill -9).
- Перезапустите контейнер: docker start redis-persist.
- Проверьте количество ключей:
redis-cli DBSIZE. Разница между записанными и восстановленными — это потеря. - Потеря должна быть не более 1 секунды (т.е. количество записей, сделанных за 1 секунду на максимальной скорости). В реальности может быть 0 или 1-2 секунды из-за задержки записи на диск.
Ожидаемый результат этапа AOF работает в режиме everysec. После жёсткого краша потеря данных не превышает 1 секунды. RDB также используется для быстрого восстановления с помощью гибридного AOF.
Этап 4: Тестирование сценариев отказа и восстановления (60 минут)
Действия
-
Сценарий A: kill -9 во время записи AOF
- Выполните массовую запись (скриптом
redis-benchmark). - Через 2 секунды после старта выполните
kill -9(в Docker:docker kill --signal=KILL redis-persist). - Перезапустите и проверьте целостность AOF: Redis автоматически выполнит
AOF rewriteпри загрузке, если файл корректен. Проверьте лог на предметReading the remaining AOF. - Если AOF повреждён — Redis может использовать
redis-check-aofдля восстановления (входит в образ).
- Выполните массовую запись (скриптом
-
Сценарий B: kill -9 во время RDB snapshot
- Установите RDB условие
save 5 1(snapshot каждые 5 секунд, если есть изменения). - Запишите один ключ, подождите 3 секунды (до снятия snapshot), затем убейте процесс.
- При старте Redis загрузит последний валидный RDB (возможно, с потерей данных, но AOF должен перекрыть).
- Проверьте, что AOF был использован для восстановления.
- Установите RDB условие
-
Сценарий C: Сбои при записи AOF (диск полный)
- Имитируйте заполнение диска (можно создать файл-заглушку).
- Наблюдайте поведение Redis: при ошибке записи AOF Redis по умолчанию переключается в режим
abort(отключает запись). Проверьте логи. - Настройте
no-appendfsync-on-rewrite no(по умолчанию) — во время перезаписи AOFfsyncне выполняется, что безопасно.
-
Сценарий D: Гибридный режим (AOF preamble)
- Убедитесь, что
aof-use-rdb-preamble yesвключён. - Сгенерируйте большой объём данных (1 млн ключей).
- Дождитесь автоматической перезаписи AOF (по достижении 64 MB или 100% роста).
- Проверьте, что новый AOF начинается с RDB-заголовка:
docker exec redis-persist head -c 100 /data/appendonly.aof | xxd. - Первые байты будут
REDIS...(RDB).
- Убедитесь, что
Ожидаемый результат этапа Полное понимание поведения Redis при различных типах отказов. Конфигурация оптимизирована для минимальной потери данных.
Этап 5: Финальная настройка и документирование (30 минут)
Действия
- Установите финальные параметры в
redis.conf:save 300 1 save 60 100 stop-writes-on-bgsave-error no rdbcompression yes rdbchecksum yes appendonly yes appendfsync everysec auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes - Настройте мониторинг персистентности:
- В
redis-cli INFO persistenceрегулярно смотритеaof_last_bgrewrite_status,rdb_last_bgsave_status. - Добавьте алерт в Prometheus/Grafana (если есть) на метрику
redis_rdb_last_save_time(если snapshot не создавался > 1 часа — предупреждение).
- В
- Напишите небольшой документ (README) с описанием конфигурации и процедурой восстановления (что делать при обнаружении повреждённого AOF).
- Зафиксируйте результаты тестов потери данных:
- Средняя потеря при
kill -9: X миллисекунд. - Максимальная зафиксированная: Y миллисекунд (должно быть < 1000 мс).
- Средняя потеря при
- Выгрузите последний исправный
redis.confи AOF-файл как артефакт.
Ожидаемый результат этапа Готовая конфигурация Redis с персистентностью и документация по эксплуатации.
5. Критерии приемки (Definition of Done)
- Redis работает с включёнными AOF (appendfsync everysec) и RDB (snapshot каждые 5 минут при >= 1 изменении).
- После
kill -9(жесткий краш) потеря данных не превышает 1 секунды (проверено минимум 3 раза). - После мягкого останова (SIGTERM) все данные восстанавливаются без потерь.
- Повреждённый AOF автоматически восстанавливается (redis-check-aof) или Redis успешно его загружает, используя
aof-load-truncated yes. - Гибридный AOF (с RDB преамбулой) включён и проверено, что файл начинается с магической строки "REDIS".
- Настроен мониторинг (INFO persistence) и написана инструкция по восстановлению.
- Все тестовые скрипты (kill, check) сохранены в репозитории.
- Конфигурация
redis.confзакоммичена в Git с комментариями.
6. Ожидаемый результат
Файлы/артефакты
redis.conf— финальная конфигурация с персистентностью.test_persistence.sh— bash-скрипт для автоматизации краш-тестов (записывает данные, убивает процесс, перезапускает, сравнивает DBSIZE).load_generator.py— Python-скрипт для высокочастотной записи (каждые 10 мс).incident_report.md— отчёт о тестах: дата, количество записанных ключей, потеря, время восстановления.docs/recovery_procedure.md— описание действий на production при сбое персистентности.
Содержание отчёта
- Результаты каждого сценария (A-D) с графиками (опционально)
- Измеренная потеря данных:
avg = 0.2 сек,max = 0.7 сек - Конфигурационные параметры и rationale
Опционально
- Docker Compose файл для быстрого развёртывания тестового окружения.
- Правила оповещения для Prometheus (
redis_up == 0,redis_rdb_last_save_time > 3600).
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
kill -9 может повредить AOF, Redis не стартует | Используйте aof-load-truncated yes для автоматического усечения последней неправильной записи. Если не помогает — запустите redis-check-aof --fix appendonly.aof перед стартом. |
Потеря данных больше 1 секунды из-за задержки fsync | Проверьте настройки appendfsync: everysec гарантирует fsync раз в секунду, но если диск сильно занят, возможна задержка. Используйте always (но резкое падение производительности). В production ставьте no только если допустима потеря. |
RDB snapshot блокирует запись во время bgsave | Параметр stop-writes-on-bgsave-error no предотвращает блокировку при ошибках. Убедитесь, что диск не переполнен. |
| Гибридный AOF не включается (старая версия Redis) | Обновитесь до 6.2+ или используйте aof-use-rdb-preamble yes. Для Redis 5 гибридный режим недоступен, тогда только AOF. |
| Размер AOF растёт бесконтрольно | Включите автоматическую перезапись: auto-aof-rewrite-percentage 100 и auto-aof-rewrite-min-size 64mb. |
| В Docker данные не сохраняются между перезапусками | Всегда монтируйте volume для /data и используйте docker stop/start, а не docker rm. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| 1. Подготовка окружения | 30 мин |
| 2. Настройка RDB | 45 мин |
| 3. Включение AOF и тест потери | 45 мин |
| 4. Сценарии отказа и восстановления | 60 мин |
| 5. Финальная настройка и документирование | 30 мин |
| Итого | ~3,5 часа |
Примечание: При первом выполнении задачи может потребоваться до 5 часов, если возникают неожиданные проблемы с Docker или версией Redis. Рекомендуется работать в изолированном контейнере, чтобы не влиять на другие проекты.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 12 | Что такое RDB и AOF в Redis? В чём отличия? |
| 18 | Как работает appendfsync? Режимы always, everysec, no. |
| 24 | Как восстановить повреждённый AOF? Команда redis-check-aof. |
| 31 | Настройка гибридного персистентного режима (RDB + AOF). |
| 45 | Мониторинг состояния персистентности Redis через INFO persistence. |
| 52 | Параметры save для планирования RDB snapshot. |
| 68 | Влияние AOF на производительность Redis. |
| 73 | Стратегии бэкапа Redis для минимизации потери данных. |
| 89 | Настройка Redis в Docker с постоянным хранением. |
| 104 | Использование BGSAVE и BGREWRITEAOF вручную. |
10. Чек-лист самопроверки
- Я умею включать RDB и AOF через
redis.confи через командыCONFIG SET. - Я могу симулировать краш (
kill -9) и перезапустить Redis с сохранением данных. - Я проверил, что после
appendfsync everysecпотеря данных не превышает 1 секунды. - Я настроил автоматическую перезапись AOF и убедился, что работает гибридный режим.
- Я написал тестовый скрипт для измерения потери данных и задокументировал результаты.
- Я понимаю разницу между мягким и жёстким крашем и знаю, как восстановить данные в каждом случае.
- Я могу объяснить коллеге, почему выбран именно такой набор параметров персистентности.