Redis: in-memory база для кэша, стримов и контекста агентов | Виталий Воробьев
VorobeoffAIВиталий Воробьев

Redis: in-memory база для кэша, стримов и контекста агентов

In-memory хранилище данных: структуры данных, персистентность, кластеризация, векторный поиск, практические сценарии от кэширования до контекстного слоя для AI-агентов.

Когда API-ответ строится за 200 миллисекунд, а база отдаёт данные за 2 — разница заметна на глаз. In-memory хранилища сокращают этот разрыв до микросекунд, и Redis за полтора десятилетия стал для этой ниши стандартом по умолчанию.

Инструмент started как простой key-value store в 2009 году и превратился в платформу: кэш, брокер сообщений, векторная база для AI-агентов, очередь задач, слой сессий. Если вы собираете систему с реальным временем отклика — Redis в стеке почти неизбежен.

Разберём, как он устроен внутри, какие структуры данных поддерживает, когда выбирать Redis вместо классической базы, и как вписать его в контур AI-приложений.

Что это

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

Ключевое отличие от PostgreSQL, MySQL или MongoDB: данные живут в RAM, не на диске. Диск нужен лишь для сохранения состояния между перезапусками. Отсюда скорость: типичная задержка на операцию — от 0,1 до 1 миллисекунды. Это как кэш процессора (L1/L2) относительно основного хранилища — быстрый слой перед медленным источником.

Ядро Redis однопоточное: команды обрабатываются в одном потоке, ввод-вывод — в нескольких. Модель параллелизма проще: блокировки и race condition на уровне команд отсутствуют. Каждая команда атомарна — либо выполняется полностью, либо не выполняется вообще.

Важно: Redis 8.8 (актуальная стабильная ветка на июль 2026) распространяется по три-лицензионной модели: RSALv2, SSPLv1 и AGPLv3. Версии 7.2 и ниже остаются под BSD-3. Форк Valkey от Linux Foundation — актуальная версия 9.1.1, BSD-лицензия, совместим по протоколу.

Зачем нужно

Redis закрывает четыре задачи, которые классические базы делают плохо или медленно: кэширование, очереди, сессии и real-time данные. Каждая из них требует микросекундного отклика, и диск-ориентированные базы здесь не конкурент.

  • Кэширование — время жизни ключа (TTL), стратегии вытеснения LRU/LFU/volatile/allkeys. Обращения к горячим данным идут из RAM, основную базу не трогают.
  • Очереди задач — Streams с consumer groups: персистентный лог событий, распределение между воркерами, подтверждение обработки.
  • Сессии и присутствие — Hashes для хранения сессий с автоматическим TTL, Sorted Sets для трекинга онлайн-пользователей.
  • Контекстный слой для AI — хранение эмбеддингов, кэширование промптов, история диалогов, векторный поиск через RediSearch.

Как устроено

Структуры данных

Redis — это не просто ключ-значение. Значение может быть одной из десятка структур, и каждая имеет свой набор команд. Это как разные типы индексов в базе: для каждой задачи — своя структура.

СтруктураЧто хранитТипичные команды
Strings
Строки, числа, сериализованные объекты. До 512 МБ на ключ
SET, GET, INCR, INCRBY, APPEND
Hashes
Поле-значение внутри ключа. Подходит для объектов: одно поле читается и пишется без разбора всего объекта
HSET, HGET, HGETALL, HINCRBY
Lists
Упорядоченная последовательность. Очереди, история сообщений
LPUSH, RPUSH, LRANGE, LTRIM
Sets
Множество уникальных значений. Теги, фильтры, объединения
SADD, SMEMBERS, SINTER, SUNION
Sorted Sets
Множество с числовым score и автосортировкой. Лидерборды, рейтинги, приоритетные очереди
ZADD, ZRANGE, ZREVRANK, ZRANGEBYSCORE
Streams
Персистентный лог событий с consumer groups. Аналог Kafka-паттерна
XADD, XREADGROUP, XACK, XGROUP
Bitmaps
Побитовые операции над строками. Счётчики, флаги
SETBIT, GETBIT, BITCOUNT
HyperLogLog
Вероятностный подсчёт уникальных элементов. Фиксированная память
PFADD, PFCOUNT, PFMERGE
Geospatial
Геокоординаты и поиск по радиусу
GEOADD, GEORADIUS, GEOSEARCH

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

Pub/Sub — рассылает события всем активным подписчикам мгновенно. Доставка без гарантий: нет подписчика в момент публикации — сообщение исчезает. Когда нужна надёжность, берите Streams с consumer groups.

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

# Терминал 2 — публикация
PUBLISH notifications '{"type": "deploy", "service": "api"}'

Персистентность

Два механизма сохранения данных на диск, и их можно комбинировать:

  • 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 к реплике, мониторинг
Redis Cluster
Большие объёмы данных, высокая пропускная способность
Автошардинг на 16 384 хэш-слота, встроенная репликация. Минимум 3 master-ноды
Redis Cloud (Active-Active)
Geo-distributed приложения
CRDT-репликация между регионами, conflict-free merge

Модули и векторный поиск

Расширения подключаются как модули: RediSearch даёт полнотекстовый поиск, RedisJSON — нативный JSON, RedisTimeSeries — ряды, RedisBloom — вероятностные структуры. Векторный поиск реализован через RediSearch — хранение эмбеддингов и k-NN поиск, что превращает Redis в контекстный слой для AI-агентов.

Транзакции и Lua

MULTI/EXEC — атомарные пакеты команд: все команды внутри выполняются как единая операция, без вмешательства других клиентов. Встроенный Lua-движок позволяет писать серверные скрипты, которые выполняются атомарно на стороне Redis.

Когда использовать

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

Самый частый сценарий: тяжёлый запрос к базе или внешнему 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-агентов

Streams в 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

Ограничение частоты вызовов методом скользящего окна на Sorted Sets. Каждый запрос добавляет timestamp в отсортированное множество, старые записи удаляются, остающиеся считаются.

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 для хранения сессий (user_id, role, last_seen) с автоматическим TTL. Sorted Sets для отслеживания онлайн-пользователей: score = timestamp последней активности.

# Сессия
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-приложений: хранение истории диалогов, кэширование промптов, управление контекстом. Списки (Lists) подходят для истории сообщений с автоматической обрезкой старых записей.

# Сохранить историю диалога
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)]

Пример

Установка

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

brew install redis
redis-server

Docker:

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

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

redis-cli ping
# PONG

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

ЯзыкБиблиотекаУстановка
Python
redis-py
pip install redis
Node.js
ioredis
npm install ioredis
Go
go-redis
go get github.com/redis/go-redis/v9
Rust
redis-rs
cargo add redis
Java
Jedis / Lettuce
Maven / 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. Managed-провайдеры (Redis Cloud, ElastiCache, Memorystore) отдают эндпоинт уже с TLS, отдельная настройка не нужна.

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

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

Команда / инструментНазначение
INFO
Полная статистика сервера: память, клиенты, репликация, keyspace
MONITOR
Реалтайм-лог всех команд (только для отладки, снижает производительность)
SLOWLOG GET 10
10 самых медленных команд
MEMORY USAGE
Сколько байт занимает конкретный ключ
Redis Insight
GUI-клиент от Redis Ltd. Визуализация данных, профилирование, просмотр Streams
redis-cli —latency
Замер латентности до сервера

Внимание: Команда KEYS * сканирует весь keyspace и блокирует сервер. В продакшене использовать SCAN с курсором, не KEYS.

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

Open Source (self-hosted)

Свободно. Пределы определяются железом: памятью, процессором, пропускной способностью сети. Лицензирование — RSALv2, SSPLv1, AGPLv3: перепродажа как managed-сервиса требует отдельной коммерческой лицензии.

Redis Cloud

ПланСтоимостьЧто входит
Free
0
30 МБ памяти, одна база, базовый набор операций. Подходит для прототипов и экспериментов
Essentials
от $5/мес
До 12 ГБ, фиксированные тарифы, TLS, ежедневные бэкапы
Pro
от $0.10-0.60/ГБ-час
Гибкие настройки, Active-Active репликация, расширения (RediSearch, RedisJSON), VPC peering, passwordless-аутентификация

Среди облачных провайдеров Redis-совместимый кэш предлагают AWS (ElastiCache), Microsoft (Azure Cache for Redis) и Google (Memorystore). Serverless-вариант — Upstash: тарификация за запрос, что удобно для бессерверных функций на Vercel и Cloudflare Workers.

Valkey (open-source форк)

Полностью бесплатный, BSD-3-лицензия. Поддерживается Linux Foundation, AWS, Google, Oracle. Текущий релиз — 9.1.1 на июль 2026. Протокол совместим с Redis, клиенты работают без изменений. Выбор в пользу Valkey оправдан, когда лицензионные рамки Redis (RSALv2/SSPL/AGPL) мешают — например, для собственного managed-сервиса.

Redis — это быстрый слой между вашим приложением и медленным хранилищем, который закрывает задачи, где диск-ориентированные базы не успевают. Кэш, очередь, сессия, контекст агента — четыре контура, где микросекунды решают.

Ограничения

ПунктПояснение

Данные в RAM — не бесплатная роскошь — Весь рабочий набор данных должен помещаться в оперативную память.

Если данных больше, чем RAM на сервере, Redis начинает вытеснять ключи по политике (allkeys-lru, volatile-lru и т.д.) или отказывать в записи. Это принципиальное ограничение in-memory архитектуры: нельзя «положить терабайт данных и надеяться, что работает». Нужно планировать объём RAM под размер рабочего набора и мониторить usage.

Однопоточное ядро — потолок одного CPU — Команды обрабатываются в одном потоке.

Это упрощает модель конкурентности, но означает, что один Redis-процесс не задействует больше одного ядра для вычислений. Для вертикального масштабирования нужен Redis Cluster — шардинг на 16 384 хэш-слота распределяет нагрузку между нодами, и каждая нода использует своё ядро. I/O потоки работают параллельно, но логика команд — последовательно.

Персистентность с риском потери данных — RDB-снапшоты делаются периодически, и между снапшотами данные можно потерять при сбое.

AOF с fsync на каждую секунду сокращает окно потери до одной секунды, но не устраняет его полностью. AOF с fsync на каждую команду даёт максимальную надёжность, но снижает пропускную способность. Нужно выбирать компромисс между скоростью и надёжностью под конкретный сценарий.

Лицензионные ограничения Redis 8+ — Три-лицензионная модель (RSALv2, SSPLv1, AGPLv3) запрещает продажу Redis как managed-сервиса без отдельной лицензии.

Для большинства приложений это не проблема, но облачным провайдерам и SaaS-платформам нужно согласовывать использование. Valkey (BSD-3) снимает это ограничение, если нужна полная свобода.

Антипаттерны

ПунктПояснение

KEYS * в продакшене — Команда KEYS * сканирует весь keyspace и блокирует сервер на время выполнения.

На больших базах это секунды блокировки, в течение которых все остальные клиенты ждут. Правильный подход — SCAN с курсором: итеративный обход, который не блокирует сервер. SCAN возвращает курсор для следующей порции, и так до полного обхода.

Pub/Sub для надёжной доставки — Pub/Sub работает без буфера: подписчик, отключённый в момент публикации, теряет сообщение навсегда.

Для очередей и event-driven архитектур, где важна гарантия доставки, нужен Streams с consumer groups — там сообщения персистентны, могут быть перечитаны и подтверждены через XACK.

Хранить всё в Strings — Если объект имеет поля, к которым нужен отдельный доступ — хранить его как сериализованную строку значит каждый раз доставать и парсить весь объект ради одного поля.

Hashes решают это: HGET достаёт одно поле за микросекунды. Аналогично: для сортированных данных — Sorted Sets, для очередей — Lists или Streams, для счётчика уникальных — HyperLogLog.

Без maxmemory и политики вытеснения — Без явного лимита памяти Redis занимает всю доступную RAM, и при исчерпании сервер падает с OOM.

Нужно установить maxmemory и выбрать политику вытеснения: allkeys-lru для чистого кэша, volatile-lru если часть ключей без TTL должна выживать, noeviction если потеря данных недопустима.

Чеклист

ПунктПояснение

Redis запущен и отвечает на PING — redis-cli ping должен вернуть PONG.

Это базовая проверка, что сервер жив и принимает соединения. Если возвращает что-то другое — проверять логи Redis, порт, firewall.

Персистентность настроена (RDB + AOF) — В redis.conf должны быть включены save-директивы для RDB и appendonly yes для AOF.

appendfsync everysec — разумный компромисс между скоростью и надёжностью для большинства сценариев.

maxmemory установлен, политика вытеснения выбрана — maxmemory задаёт верхний предел потребления RAM.

Политика allkeys-lru — стандарт для кэша: при нехватке памяти Redis удаляет наименее недавно использованные ключи. noeviction — для баз данных, где потеря ключей недопустима.

Пароль задан, TLS включён в продакшене — requirepass в redis.conf или переменная окружения.

Для managed-сервисов (Redis Cloud, ElastiCache) — TLS из коробки. Redis без пароля в открытой сети — уязвимость: команда CONFIG GET позволяет читать и менять конфигурацию сервера.

TTL установлен на все кэшируемые ключи — Ключи без TTL живут вечно и постепенно забивают память.

Каждый кэшируемый ключ должен иметь ex= параметр. Мониторинг: INFO keyspace показывает количество ключей с и без TTL.

Мониторинг подключён — INFO даёт статистику по памяти, клиентам, репликации.

SLOWLOG — медленные команды. Алерты на memory usage > 80% и на рост SLOWLOG — минимальный набор для продакшена.

Бэкапы RDB выгружаются на внешнее хранилище — RDB-файл на том же сервере что и Redis — не бэкап.

Нужна регулярная выгрузка на S3, отдельный диск или другой сервер. Минимум — раз в сутки, для нагруженных систем — чаще.

Latency проверена через redis-cli —latency — Замеряет задержку до сервера в реальном времени.

Норма для локального сервера — менее 1 миллисекунды. Повышение латентности — сигнал нагрузки, проблем с сетью или необходимости масштабирования.

Ссылки

Продолжить тему

Материалы, которые связаны с этим разбором

Подборка учитывает тему, редкие теги и смысл заголовка с описанием материала.

Открыть материалы по теме ↗

Обсудить задачу

Есть задача, которую хотите усилить с помощью ИИ?

Опишите процесс, что уже пробовали и какой результат хотите получить. Я помогу понять, где ИИ и автоматизация действительно дадут эффект, и предложу понятный следующий шаг.

Для первого сообщения достаточно пары абзацев — готовое техническое задание не требуется.