Механизмы персистентности, настройка производительности, memory management
Redis — in-memory база данных, но данные можно сохранять на диск для восстановления после перезапуска. Два механизма: RDB (снапшоты) и AOF (лог операций). Правильная настройка персистентности и памяти критична для production.
RDB — создание снапшотов данных на диск в определённые интервалы.
# redis.conf
# Сохранять если:
# - прошло 900 секунд (15 минут) И изменён хотя бы 1 ключ
# - прошло 300 секунд (5 минут) И изменено хотя бы 10 ключей
# - прошло 60 секунд (1 минута) И изменено хотя бы 10000 ключей
save 900 1
save 300 10
save 60 10000
# Имя файла снапшота
dbfilename dump.rdb
# Директория для файла
dir /var/lib/redis
# Сжатие строк
rdbcompression yes
# Контрольная сумма (защита от повреждения)
rdbchecksum yes
# Stop writes при ошибке сохранения
stop-writes-on-bgsave-error yes# Синхронное сохранение (блокирует Redis до завершения)
SAVE
# Асинхронное сохранение (не блокирует)
BGSAVE
# Проверка статуса BGSAVE
LASTSAVE # Возвращает timestamp последнего успешного сохранения
# Принудительное сохранение в RDB
BGSAVE SCHEDULE # Запланировать, если уже идёт BGSAVE| Плюсы | Минусы |
|---|---|
| Быстрое восстановление | Потеря данных за последний интервал |
| Компактный файл | Блокировка при SAVE (не BGSAVE) |
| Подходит для бэкапов | Fork может потреблять память |
AOF — логирование всех операций записи. Надёжнее, но медленнее RDB.
# redis.conf
# Включить AOF
appendonly yes
# Имя файла
appendfilename "appendonly.aof"
# Синхронизация с диском:
# always - каждый запрос (медленно, надёжно)
# everysec - раз в секунду (баланс) ← рекомендуется
# no - ОС решает (быстро, риск потери)
appendfsync everysec
# Не делать fsync во время rewrite
no-appendfsync-on-rewrite no
# Автоматический rewrite при росте на 100%
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# Load truncated AOF при ошибке
aof-load-truncated yes
# Использовать RDB preamble для быстрого load
aof-use-rdb-preamble yes# Включить AOF динамически
CONFIG SET appendonly yes
# Принудительный rewrite (сжатие)
BGREWRITEAOF
# Проверка статуса
INFO persistence
# Отключить AOF (не рекомендуется)
CONFIG SET appendonly no| Плюсы | Минусы |
|---|---|
| Надёжнее (потеря макс 1 сек) | Больше файл |
| Можно откатить операции | Медленнее восстановление |
| Нет блокировок | Fork при rewrite |
Рекомендуемый подход для production: RDB + AOF.
# redis.conf для production
# RDB для быстрого восстановления
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
# AOF для надёжности
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes
# При загрузке Redis предпочитает AOF (он новее)При запуске Redis загружает AOF (он содержит более свежие данные), RDB используется как fallback.
# redis.conf
# Максимальный объём памяти для данных
# Рекомендуется 70-80% от доступной RAM
maxmemory 4gb
# Политика вытеснения при заполнении
maxmemory-policy allkeys-lru| Политика | Описание | Use case |
|---|---|---|
| noeviction | Возвращать ошибку при нехватке памяти | Критичные данные, нельзя терять |
| allkeys-lru | Удалять наименее недавно используемые ключи | Кэширование |
| volatile-lru | Удалять LRU ключи с установленным TTL | Кэш + важные данные без TTL |
| allkeys-random | Удалять случайные ключи | Равномерное распределение |
| volatile-random | Удалять случайные ключи с TTL | Кэш с TTL |
| volatile-ttl | Удалять ключи с ближайшим TTL | Временные данные |
| allkeys-lfu | Удалять наименее часто используемые | Популярный контент |
| volatile-lfu | Удалять LFU ключи с TTL | Кэш с учётом частоты |
# Для кэширования API
maxmemory-policy allkeys-lru
# Для сессий и временных данных
maxmemory-policy volatile-ttl
# Для смешанной нагрузки
maxmemory-policy volatile-lru
# Для LFU (Redis 4+)
maxmemory-policy allkeys-lfu# Информация о памяти
INFO memory
# Ключевые метрики:
# used_memory — память для данных
# used_memory_rss — память процесса (OS)
# used_memory_peak — пиковое потребление
# used_memory_lua — память Lua скриптов
# maxmemory — установленный лимит
# mem_fragmentation_ratio — used_memory_rss / used_memory
# Детальная информация
MEMORY STATS
# Поиск ключей, потребляющих много памяти
MEMORY USAGE key # Размер ключа в байтах
# Найти самые большие ключи
redis-cli --bigkeys# Проверка фрагментации
INFO memory | grep fragmentation
# fragmentation_ratio > 1.5 — высокая фрагментация
# fragmentation_ratio < 1 — swap (плохо)
# Решение: перезапуск Redis или
MEMORY DOCTOR # Диагностика проблем# redis.conf
# Максимальный размер клиента
maxclients 10000
# Таймаут бездействия клиента (0 = отключено)
timeout 300
# TCP keepalive
tcp-keepalive 300
# Размер backlog для репликации
repl-backlog-size 1mb
# TCP backlog
tcp-backlog 511# Логирование медленных запросов
# Порог в микросекундах (10000 мкс = 10 мс)
slowlog-log-slower-than 10000
# Максимум записей в логе
slowlog-max-len 128# Просмотр slow log
SLOWLOG GET 10 # Последние 10 записей
SLOWLOG LEN # Количество записей
SLOWLOG RESET # Очистить лог
# Анализ запросов
SLOWLOG GET 10 WITHSUMMARY# Мониторинг latency в реальном времени
redis-cli --latency
# Latency по командам
redis-cli --latency-history
# Встроенный мониторинг
LATENCY DOCTOR # Диагностика проблем
LATENCY HISTORY # История latency событий
LATENCY GRAPH # График (в redis-cli)# Hash оптимизация
hash-max-ziplist-entries 512 # Compact storage до 512 полей
hash-max-ziplist-value 64 # Compact storage до 64 байт на значение
# List оптимизация
list-max-ziplist-size -2 # -2 = 8KB max per node
list-compress-depth 1 # Сжатие узлов
# Set оптимизация
set-max-intset-entries 512 # Compact storage для int sets
# Sorted Set оптимизация
zset-max-ziplist-entries 128
zset-max-ziplist-value 64# ========================
# Production Redis Config
# ========================
# Сеть
bind 127.0.0.1
port 6379
protected-mode yes
tcp-backlog 511
timeout 300
tcp-keepalive 300
# Безопасность
requirepass SuperSecretPassword123!
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command KEYS ""
# Персистентность
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
rdbcompression yes
rdbchecksum yes
stop-writes-on-bgsave-error yes
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
# Память
maxmemory 4gb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# Клиенты
maxclients 10000
# Slow log
slowlog-log-slower-than 10000
slowlog-max-len 128
# Логирование
loglevel notice
logfile /var/log/redis/redis-server.log
# Оптимизация структур
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64version: '3.8'
services:
redis:
image: redis:7-alpine
container_name: redis_prod
command: >
redis-server
--appendonly yes
--maxmemory 4gb
--maxmemory-policy allkeys-lru
--requirepass ${REDIS_PASSWORD}
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
- ./redis.conf:/usr/local/etc/redis/redis.conf
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
deploy:
resources:
limits:
memory: 5G
volumes:
redis_data:# Синхронный бэкап (блокирует Redis)
redis-cli SAVE
cp /var/lib/redis/dump.rdb /backup/dump-$(date +%Y%m%d).rdb
# Асинхронный бэкап (не блокирует)
redis-cli BGSAVE
# Ждём завершения
while [ $(redis-cli LASTSAVE) -eq $LASTSAVE ]; do sleep 1; done
cp /var/lib/redis/dump.rdb /backup/dump-$(date +%Y%m%d).rdb
# Бэкап с другого сервера
redis-cli -h redis.internal --rdb /backup/dump.rdb# Остановка Redis
systemctl stop redis
# Копирование бэкапа
cp /backup/dump-20260302.rdb /var/lib/redis/dump.rdb
chown redis:redis /var/lib/redis/dump.rdb
# Запуск Redis
systemctl start redis
# Проверка
redis-cli INFO persistence | grep rdb_last_load_status#!/bin/bash
# backup-redis.sh
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d-%H%M%S)
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD="${REDIS_PASSWORD}"
# Создание бэкапа
redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD BGSAVE
sleep 5 # Ждём начала сохранения
# Проверка завершения
while true; do
LASTSAVE=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD LASTSAVE)
if [ $LASTSAVE -gt $LASTSAVE_PREV ]; then
break
fi
LASTSAVE_PREV=$LASTSAVE
sleep 1
done
# Копирование файла
cp /var/lib/redis/dump.rdb $BACKUP_DIR/dump-$DATE.rdb
# Сжатие
gzip $BACKUP_DIR/dump-$DATE.rdb
# Удаление старых бэкапов (хранить 7 дней)
find $BACKUP_DIR -name "dump-*.rdb.gz" -mtime +7 -delete
echo "Backup completed: dump-$DATE.rdb.gz"# Crontab: бэкап каждый день в 3:00
0 3 * * * /usr/local/bin/backup-redis.sh >> /var/log/redis-backup.log 2>&1Проверьте понимание → ответьте на вопросы в persistence.json
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.