Гайды
Основы Redis: кеширование и структуры данных
Строки, хеши, списки, множества, sorted sets, cache-aside, eviction, TTL и типичные ошибки в продакшене.
~10 мин чтения
Основы Redis: кеширование и структуры данных
Redis — хранилище структур данных в памяти с моделью «ключ → значение» и примитивами: списки, множества, sorted sets, хеши, потоки и др. Чаще всего его используют как кеш, простые очереди, сессии и rate limiting. Pub/Sub и очереди на Lists подробнее — в гайде Redis Pub/Sub и очереди через Lists.
1. Архитектура: что держать в голове
- В классической модели один поток команд — долгие команды блокируют остальные;
KEYSв проде — антипаттерн. - Всё в RAM — при исчерпании памяти срабатывают
maxmemoryи eviction (или OOM). - Durability опциональна: RDB (снимки), AOF (журнал команд) — компромисс скорость / потеря последних секунд.
- Горизонтальное масштабирование — Redis Cluster или шардирование на уровне приложения.
2. Установка и redis-cli
docker run -d --name redis -p 6379:6379 redis:7-alpine
redis-cli -h 127.0.0.1 -p 6379 ping
# PONG
В redis.conf: bind, requirepass или ACL (ACL SETUSER), maxmemory, maxmemory-policy.
3. Строки (String)
SET user:1001:name "Alice"
GET user:1001:name
SET counter:views:post-9 0
INCR counter:views:post-9
INCRBY counter:views:post-9 10
SET session:abc token-value EX 3600
EX / PX / EXAT — TTL или абсолютное время. MGET / MSET — меньше round-trip.
4. Хеши (Hash)
HSET user:1001 name "Alice" email "a@example.com" plan "pro"
HGET user:1001 email
HGETALL user:1001
HINCRBY user:1001 logins 1
Меньше ключей в keyspace, чем плоский user:1001:email; TTL на весь объект проще.
5. Списки (List)
LPUSH jobs:pending "task-1" "task-2"
RPOP jobs:pending
LLEN jobs:pending
LRANGE jobs:pending 0 -1
BRPOP — блокирующее чтение. Паттерны очередей — в отдельном гайде.
6. Set и Sorted Set
Set:
SADD tags:post:9 redis database
SISMEMBER tags:post:9 redis
SMEMBERS tags:post:9
Sorted set (score + member):
ZADD leaderboard 9800 "player:1"
ZADD leaderboard 10200 "player:2"
ZREVRANGE leaderboard 0 9 WITHSCORES
ZRANK leaderboard "player:1"
Удобно для топ-N и отложенных задач по score = время (ZRANGEBYSCORE).
7. Bitmap и HyperLogLog (кратко)
- Bitmaps (
SETBIT/GETBIT) — компактные флаги; следите за размером keyspace. - HyperLogLog (
PFADD/PFCOUNT) — оценка кардинальности с погрешностью и малой памятью.
8. Кеш: cache-aside
- Читать Redis.
- При miss — БД, положить в Redis с TTL.
- При записи в БД — обновить или инвалидировать ключ.
Cache stampede: много промахов одновременно → все в БД. Лечение: singleflight, вероятностный ранний refresh TTL, SET nx на пересчёт.
Вероятностные структуры (модуль RedisBloom: Bloom / Cuckoo) удобны для «точно нет / возможно да» перед дорогим запросом в БД. Client-side caching (CLIENT TRACKING) в Redis 6+ снижает сетевой round-trip для горячих ключей — полезно вместе с библиотекой, поддерживающей invalidation.
9. Политики eviction (maxmemory-policy)
| Политика | Поведение |
|---|---|
noeviction | Ошибка на запись при полной памяти |
allkeys-lru | LRU среди всех ключей |
volatile-lru | Среди ключей с TTL |
allkeys-lfu / volatile-lfu | По частоте (Redis 4+) |
10. Транзакции и pipeline
MULTI … EXEC — атомарный блок команд (не SQL-транзакция с откатом по ошибке внутри блока — модель Redis своя).
Pipeline в клиенте — пакетирование без ожидания ответа на каждую команду → ниже latency.
11. Прод: безопасность
- Не открывайте 6379 в интернет без TLS, ACL и firewall.
- Разделение по сервисам — префиксы ключей и дисциплина, не замена изоляции.
- Persistence + backup для данных, которые нельзя потерять при рестарте.
- Мониторинг:
INFO, latency, экспортеры Prometheus.
12. Типичные ошибки
| Ошибка | Эффект |
|---|---|
KEYS * в проде | Блокировка, всплеск latency |
| Нет TTL на кеш | Рост памяти до eviction/OOM |
| Огромные JSON без сжатия | RAM и сеть |
| Redis как единственная БД без AOF/RDB | Потеря данных |
| Один инстанс без реплики | SPOF |
13. SCAN вместо KEYS
Для админских задач и миграций префикса используйте SCAN cursor MATCH pattern COUNT hint — итерация без блокировки всего keyspace, как у KEYS. В redis-py: for key in client.scan_iter(match="cache:user:*", count=500): .... На кластере SCAN идёт по одному шарду за раз; для полного обхода нужны обходы по мастерам слотов или согласованный дизайн ключей.
См. также
- Pub/Sub и очереди в Redis
- JSONB в PostgreSQL — когда документы лучше в СУБД