База знаний

Redis — in-memory хранилище данных для кэширования, очередей и реального времени

Полный справочник по Redis: архитектура, структуры данных, Pub/Sub, Streams, кластеризация, тарифы и практические сценарии для AI-агентов и веб-приложений.

Опубликовано

In-memory хранилище данных с открытым исходным кодом. Используется как кэш, брокер сообщений, база данных реального времени и контекстный слой для AI-приложений. Работает со скоростью микросекунд, поддерживает десятки структур данных и масштабируется от одного процесса до geo-distributed кластера.

Что такое Redis

Redis (Remote Dictionary Server) — хранилище данных в оперативной памяти, которое отдаёт ответы за единицы микросекунд. Создатель — Сальваторе Санфилиппо (antirez). Проект стартовал в 2009 году как простой key-value store, но за 17 лет превратился в полноценную платформу для работы с данными в реальном времени.

Главное отличие от классических баз данных: данные живут в RAM, а не на диске. Диск используется только для персистентности — чтобы не потерять всё при перезагрузке. Отсюда скорость: типичная latency — от 0,1 до 1 мс на операцию.

Redis — однопоточный по дизайну (ядро обрабатывает команды в одном потоке, I/O — в нескольких). Это упрощает модель конкурентности: нет блокировок, нет race conditions на уровне команд. Каждая команда атомарна.

📌
Redis 8.x (текущая стабильная ветка) — полностью open source под лицензией RSALv2/SSPL. Форк Valkey (Linux Foundation) использует BSD-лицензию и совместим по протоколу.

Основные возможности

ВозможностьОписание
КэшированиеTTL на ключах, политики вытеснения (LRU, LFU, volatile, allkeys), максимально быстрый доступ к горячим данным
Структуры данныхStrings, Hashes, Lists, Sets, Sorted Sets, Streams, Bitmaps, HyperLogLog, Geospatial indexes
Pub/SubЛегковесная широковещательная рассылка сообщений подписчикам в реальном времени. Сообщения не персистентны — доставляются только активным подписчикам
StreamsПерсистентный лог событий с consumer groups (аналог Kafka-паттерна). Подходит для очередей задач и event-driven архитектур
Транзакции и LuaMULTI/EXEC для атомарных пакетов команд, встроенный Lua-движок для серверных скриптов
ПерсистентностьRDB-снапшоты (периодические дампы) и AOF (append-only file, журнал операций). Можно комбинировать
КластеризацияRedis Cluster — автоматический шардинг на 16 384 хэш-слота, встроенная репликация и failover
МодулиRediSearch (полнотекстовый поиск), RedisJSON (нативная работа с JSON), RedisTimeSeries, RedisBloom (вероятностные структуры)
Векторный поискЧерез модуль RediSearch — хранение эмбеддингов и k-NN поиск. Используется как контекстный слой для AI-агентов

Интеграция и подключение

Установка

Локально (macOS):

brew install redis
redis-server

Docker:

docker run -d --name redis -p 6379:6379 redis:8-alpine

Проверка соединения:

redis-cli ping
# PONG

Клиентские библиотеки

ЯзыкБиблиотекаУстановка
Pythonredis-pypip install redis
Node.jsioredisnpm install ioredis
Gogo-redisgo get github.com/redis/go-redis/v9
Rustredis-rscargo add redis
JavaJedis / LettuceMaven / Gradle

Подключение из Python

import redis

r = redis.Redis(host="localhost", port=6379, decode_responses=True)

# Записать и прочитать
r.set("user:1:name", "Sergey", ex=3600)  # TTL 1 час
name = r.get("user:1:name")
print(name)  # Sergey

# Hash
r.hset("session:abc", mapping={"user_id": "1", "role": "admin"})
session = r.hgetall("session:abc")

Подключение из Node.js

import Redis from "ioredis";

const redis = new Redis(); // localhost:6379

await redis.set("cache:prices", JSON.stringify({ usd: 92.5 }), "EX", 300);
const prices = JSON.parse(await redis.get("cache:prices"));

Авторизация и TLS

В продакшене Redis защищается паролем (requirepass в конфиге) и TLS. Redis Cloud и managed-сервисы предоставляют endpoint с TLS из коробки.

# Подключение с паролем и TLS
redis-cli -h my-redis.cloud.redislabs.com -p 16379 --tls --askpass

Ключевые структуры данных

Strings

Базовый тип. Хранит строки, числа, сериализованные объекты. Максимальный размер — 512 МБ.

SET counter 0
INCR counter        # 1
INCRBY counter 10   # 11

Hashes

MAP внутри ключа. Удобно для объектов — не нужно сериализовать весь объект ради одного поля.

HSET user:1 name "Sergey" role "admin" score 42
HGET user:1 name    # "Sergey"
HINCRBY user:1 score 5  # 47

Sorted Sets

Множество с числовым score. Автоматическая сортировка. Идеально для лидербордов, рейтингов, приоритетных очередей.

ZADD leaderboard 1500 "alice" 2300 "bob" 1800 "carol"
ZRANGE leaderboard 0 -1 WITHSCORES  # alice 1500, carol 1800, bob 2300
ZREVRANK leaderboard "bob"           # 0 (первое место)

Streams

Персистентный лог с consumer groups. Каждое сообщение имеет автоматический ID (timestamp + sequence).

# Продюсер
XADD events * type "order" amount 1500

# Consumer group
XGROUP CREATE events workers $ MKSTREAM
XREADGROUP GROUP workers agent-1 COUNT 10 BLOCK 5000 STREAMS events >

# Подтверждение
XACK events workers 1715356800000-0
💡
Streams — основной инструмент для построения очередей задач в Redis. В отличие от Pub/Sub, сообщения сохраняются и могут быть перечитаны. Consumer groups позволяют распределять нагрузку между воркерами.

Pub/Sub — широковещательные сообщения

Pub/Sub подходит для уведомлений, live-обновлений и событийной архитектуры, где потеря отдельного сообщения некритична.

# Терминал 1 — подписчик
SUBSCRIBE notifications

# Терминал 2 — публикация
PUBLISH notifications '{"type": "deploy", "service": "api"}'
⚠️
Pub/Sub не сохраняет сообщения. Если подписчик отключён в момент публикации — сообщение потеряно. Для гарантированной доставки используйте Streams с consumer groups.

Персистентность и резервное копирование

Redis предлагает два механизма сохранения данных на диск:

  • RDB (снапшоты) — периодические дампы всей базы. Компактный формат, быстрая загрузка при старте. Можно потерять данные между снапшотами.
  • AOF (append-only file) — журнал каждой операции записи. Можно настроить fsync на каждую секунду или каждую команду. Надёжнее, но файл больше.

Рекомендация для продакшена: включить оба. RDB для быстрого восстановления, AOF для минимальной потери данных.

# redis.conf
save 900 1        # RDB: снапшот если >= 1 изменение за 900 сек
save 300 10       # или >= 10 изменений за 300 сек
appendonly yes    # AOF включён
appendfsync everysec  # fsync раз в секунду

Кластеризация и масштабирование

РежимКогда использоватьОсобенности
StandaloneРазработка, небольшие проекты до 25 ГБОдин процесс, максимальная простота
SentinelПродакшен без шардингаАвтоматический failover master → replica, мониторинг
Redis ClusterБольшие объёмы данных, высокая пропускная способностьАвтошардинг на 16 384 слота, встроенная репликация. Минимум 3 master-ноды
Redis Cloud (Active-Active)Geo-distributed приложенияCRDT-репликация между регионами, conflict-free merge

Тарифы и лимиты

Open Source (self-hosted)

Бесплатно. Ограничения — только ваш сервер: объём RAM, CPU, сеть. Лицензия RSALv2/SSPL (нельзя продавать Redis как managed service).

Redis Cloud

ПланСтоимостьЧто входит
Free0 ₽30 МБ RAM, 1 база, базовые операции. Для экспериментов и прототипов
Essentialsот $5/мес (около 500 ₽)До 12 ГБ, фиксированные тарифы, TLS, ежедневные бэкапы
Proот $0,10–0,60/ГБ-часГибкие конфигурации, Active-Active, модули (RediSearch, RedisJSON), VPC peering, passwordless auth
💡
Альтернативы managed Redis: AWS ElastiCache, Azure Cache for Redis, Google Memorystore, Upstash (serverless, оплата за запрос — удобно для Vercel/Cloudflare Workers).

Valkey (open-source форк)

Полностью бесплатный, BSD-лицензия. Поддерживается Linux Foundation, AWS, Google, Oracle. Совместим по протоколу с Redis. Подходит, если нужна managed-инфраструктура без ограничений RSALv2.

Практические сценарии

Кэширование API-ответов

Самый распространённый сценарий. Сохраняете результат тяжёлого запроса с TTL — следующие обращения отдаются из памяти.

import json, redis, requests

r = redis.Redis(host="localhost", port=6379, decode_responses=True)

def get_weather(city: str) -> dict:
    cached = r.get(f"weather:{city}")
    if cached:
        return json.loads(cached)
    
    response = requests.get(f"https://api.weather.com/{city}")
    data = response.json()
    r.set(f"weather:{city}", json.dumps(data), ex=600)  # кэш на 10 минут
    return data

Очередь задач для AI-агентов

Redis Streams — готовая инфраструктура для распределения задач между агентами.

# Продюсер — добавляет задачу
r.xadd("agent:tasks", {"type": "summarize", "url": "https://example.com/article"})

# Воркер — забирает и обрабатывает
messages = r.xreadgroup(
    groupname="workers",
    consumername="agent-1",
    streams={"agent:tasks": ">"},
    count=1,
    block=5000
)

Rate limiting

Ограничение частоты запросов через sliding window на Sorted Sets.

import time

def is_rate_limited(user_id: str, limit: int = 100, window: int = 60) -> bool:
    key = f"ratelimit:{user_id}"
    now = time.time()
    
    pipe = r.pipeline()
    pipe.zremrangebyscore(key, 0, now - window)  # убрать старые
    pipe.zadd(key, {str(now): now})               # добавить текущий
    pipe.zcard(key)                               # посчитать
    pipe.expire(key, window)                      # TTL на ключ
    _, _, count, _ = pipe.execute()
    
    return count > limit

Сессии и real-time присутствие

Hashes для хранения сессий, Sorted Sets для отслеживания онлайн-пользователей.

# Сессия
HSET session:token123 user_id 1 role admin last_seen 1715356800
EXPIRE session:token123 3600

# Онлайн-пользователи (score = timestamp последней активности)
ZADD online_users 1715356800 "user:1"
ZRANGEBYSCORE online_users 1715356740 +inf  # активные за последнюю минуту

Контекстный слой для AI-приложений

Redis используется как memory layer для LLM-приложений: хранение эмбеддингов, кэширование промптов, управление conversation history.

# Сохранить историю диалога
r.lpush("chat:session:abc", json.dumps({"role": "user", "content": "Что такое Redis?"}))
r.lpush("chat:session:abc", json.dumps({"role": "assistant", "content": "Redis — это..."}))
r.ltrim("chat:session:abc", 0, 49)  # хранить последние 50 сообщений
r.expire("chat:session:abc", 86400)  # TTL 24 часа

# Прочитать контекст для следующего запроса к LLM
history = [json.loads(m) for m in r.lrange("chat:session:abc", 0, -1)]

Мониторинг и отладка

Команда / инструментНазначение
INFOПолная статистика сервера: память, клиенты, репликация, keyspace
MONITORРеалтайм-лог всех команд (только для отладки, снижает производительность)
SLOWLOG GET 1010 самых медленных команд
MEMORY USAGE <key>Сколько байт занимает конкретный ключ
Redis InsightGUI-клиент от Redis Ltd. Визуализация данных, профилирование, просмотр Streams
redis-cli --latencyЗамер латентности до сервера
⚠️
Никогда не используйте KEYS * в продакшене — команда сканирует весь keyspace и блокирует сервер. Используйте SCAN с курсором.

Чеклист быстрой проверки

Redis запущен и отвечает на PING
Персистентность настроена (RDB + AOF)
maxmemory установлен, политика вытеснения выбрана (allkeys-lru для кэша)
Пароль задан (requirepass), TLS включён в продакшене
KEYS * нигде не используется — только SCAN
TTL установлен на все кэшируемые ключи
Мониторинг подключён (INFO, алерты на memory usage)
Бэкапы RDB выгружаются на внешнее хранилище
Для очередей используются Streams (а не Pub/Sub)
Latency проверена: redis-cli --latency

Ссылки


По теме

Redis часто становится первым инструментом, который появляется в стеке, когда проект перерастает файловый кэш. Если вы строите систему с реальным временем отклика или хотите разобраться, как вписать Redis в архитектуру AI-агентов, — пишите в Telegram @pimenov