
Redis — полный разбор от первой команды до продакшна
Я использую Redis в своих проектах уже какое-то время. Сначала просто добавил его в свое радио Rockify для хранения текущего состояния эфира - и не особо задумывался как он устроен внутри. Потом начал разбираться глубже. Вот что я понял.
Почему Redis существует
Представь простую ситуацию. У тебя есть сайт. Когда пользователь открывает страницу - твой код идёт в базу данных, делает запрос, получает данные, отдаёт их пользователю.
Работает нормально когда пользователей 10. Но что если их 10 000 одновременно? И все они запрашивают одни и те же данные которые меняются раз в час?
Ты делаешь 10 000 одинаковых запросов к базе данных. Это медленно, дорого и совершенно бессмысленно.
Фундаментальная проблема в разнице скоростей:
- Диск (где живёт база данных) — медленный. Чтение занимает миллисекунды
- RAM (оперативная память) — в 100–1000 раз быстрее. Чтение в микросекундах
Redis - это in-memory база данных. Она живёт в RAM. Вот почему она такая быстрая.
Его создал Salvatore Sanfilippo в 2009 году - просто потому что устал от медленного веб-приложения. Сейчас Redis используют Twitter, GitHub, Stripe и миллионы других проектов.
Кэширование - главный сценарий использования
Кэш - это копия часто используемых данных в RAM, чтобы не ходить за ними на диск каждый раз.
Схема работы:
Запрос пришёл → проверяем Redis
├── Данные есть (Cache Hit) → отдаём мгновенно ✓
└── Данных нет (Cache Miss) → идём в БД → кладём в Redis → отдаём
Первые три команды которые нужно знать:
SET notes:count 42 # Сохранить
GET notes:count # Получить → "42"
DEL notes:count # Удалить
INCR notes:count # Атомарно прибавить 1 → "43"
INCR - особенно интересная команда. Она атомарная - даже если 1000 пользователей вызовут её одновременно, счётчик всегда будет точным. Именно так считаются просмотры, лайки, количество заказов в реальном времени.
В Node.js это выглядит так:
const redis = require('redis')
const client = redis.createClient({ url: 'redis://localhost:6379' })
await client.connect()
// Кэшируем заметки
await client.set('notes:latest', JSON.stringify(notes), { EX: 300 }) // 5 минут
// Получаем
const cached = await client.get('notes:latest')
if (cached) return JSON.parse(cached) // Cache Hit — мгновенно
Структуры данных - в этом вся сила Redis
Redis - не просто хранилище строк. Он понимает структуру данных. Это меняет всё.
Hashes - объекты
Вместо того чтобы хранить объект как JSON-строку - храним его поля отдельно:
HSET track:1 title "Кино - Группа крови" plays 0 artist "Кино"
HGET track:1 title # → "Кино - Группа крови"
HINCRBY track:1 plays 1 # атомарно увеличиваем счётчик воспроизведений
В своем радио я использую именно это - каждый трек хранится как Hash, счётчик воспроизведений обновляется атомарно при каждом запуске.
Lists - очереди
Упорядоченный список элементов. Добавляем в конец - забираем с начала:
RPUSH playlist:queue "track:1" "track:2" "track:3"
LPOP playlist:queue # → "track:1" (убирает из списка)
LRANGE playlist:queue 0 -1 # посмотреть всё
Использую для хранения истории воспроизведения треков в Rockify - последние 50 треков всегда в Redis.
Sets - уникальные коллекции
Дубликаты невозможны. Можно искать пересечения между множествами:
SADD genres:rock "Кино" "ДДТ" "Алиса"
SADD genres:classic "Кино" "Наутилус"
SINTER genres:rock genres:classic # → "Кино"
Sorted Sets - рейтинги и лидерборды
Автоматически сортирует элементы по числовому score:
ZADD artists:popular 150 "Кино"
ZADD artists:popular 300 "ДДТ"
ZADD artists:popular 50 "Алиса"
ZREVRANGE artists:popular 0 2 # топ-3 артиста
Именно так работают рейтинги треков в Rockify - чем реже трек играл в последнее время, тем выше его шанс попасть в эфир.
TTL - данные которые сами себя удаляют
RAM дорогая. Хранить всё вечно нельзя. Поэтому у Redis есть TTL - Time To Live, срок жизни ключа:
SET session:user:99 "active" EX 3600 # исчезнет через 1 час
TTL session:user:99 # сколько секунд осталось
Когда TTL истекает - Redis сам удаляет ключ. Тебе ничего не надо делать.
Где это применяется:
- Сессии пользователей
- Кэш запросов к API (обновляем каждые 5 минут)
- Одноразовые коды подтверждения
- Счётчик просмотров страницы
Паттерны кэширования
Когда Redis стоит перед базой данных - нужно решить как они взаимодействуют. Три основных паттерна:
Cache-Aside (самый популярный)
Проверяй кэш. Есть - отдавай. Нет - иди в БД, положи в кэш, отдавай. Минус: пока TTL не истёк, кэш может показывать устаревшие данные.
Write-Through
Пишешь одновременно в Redis и в БД. Кэш всегда актуален. Минус: запись медленнее.
Write-Behind
Пишешь только в Redis, БД обновляется в фоне. Максимальная скорость. Минус: при сбое можно потерять данные.
Начинай с Cache-Aside. Это решает 95% задач безопасно.
Pub/Sub и Streams - реальное время
Pub/Sub - система сообщений «опубликовал и забыл»:
# Подписчик слушает канал
SUBSCRIBE now_playing
# Издатель отправляет сообщение
PUBLISH now_playing "Кино - Группа крови"
Мгновенно - все подписчики получают сообщение. Именно так работает обновление «что сейчас играет» на сайте Rockify в реальном времени.
Минус Pub/Sub: если подписчик отключился в момент отправки - сообщение потеряно навсегда.
Streams - решают эту проблему. Это как Pub/Sub но с памятью:
XADD events * type "track_played" track_id "track:1"
XRANGE events - + # читаем всю историю
Streams хранят все события. Подключился позже - можешь прочитать всё что пропустил. Это Redis-альтернатива Kafka для большинства задач.
Персистентность - что происходит при перезагрузке
Redis живёт в RAM. RAM энергозависима. Что будет если сервер перезапустится?
Два варианта:
RDB (снапшоты)
Redis периодически делает «фотографию» всей RAM и сохраняет на диск. Быстрый старт, компактный файл. Минус: можно потерять данные за последние N минут.
AOF (лог операций)
Redis записывает каждую команду в файл. При перезапуске - проигрывает все команды заново. Почти ничего не теряешь. Минус: файл большой, старт медленнее.
Практический совет: используй оба. AOF для надёжности, RDB для быстрых бэкапов.
Если Redis у тебя чисто как кэш - и при перезапуске данные всё равно придут из БД - можно отключить персистентность совсем. Так делаю я в Rockify для кэша меню треков.
Масштабирование
Когда один сервер не справляется - Redis масштабируется тремя способами:
Replication (репликация)
Один Primary принимает запись. Несколько Replica читают. Миллион пользователей смотрят каталог - нагрузка распределяется по репликам. Primary только принимает изменения.
# На сервере-реплике:
REPLICAOF primary-ip 6379
Sentinel (автоматическое восстановление)
Следит за Primary. Если он упал - автоматически продвигает Replica в Primary. Ты спишь, система сама восстанавливается.
Cluster (шардирование)
Данные делятся на 16 384 слота и распределяются по нескольким серверам. Каждый сервер отвечает за свою часть. Нужен когда данных больше чем влезает в RAM одного сервера.
Redis и ИИ
Неожиданный поворот - но очень актуальный в 2026 году.
Память для ИИ-ассистентов
LLM не помнят контекст между запросами. История диалога хранится в Redis Lists и передаётся модели при каждом новом сообщении:
// Сохраняем историю диалога
await client.rPush(`chat:${userId}`, userMessage)
// Берём последние 10 сообщений для контекста
const history = await client.lRange(`chat:${userId}`, -10, -1)
Vector Search
Redis умеет искать по смысловой близости - не по точному совпадению слов. Пользователь ищет «здоровая еда» - находит «Veggie Supreme» потому что математически они близки. Это основа современных рекомендательных систем.
Главные ограничения
Redis не серебряная пуля. Важно понимать когда его не использовать:
RAM дорогая. Не храни в Redis всю базу данных. Только горячие, часто запрашиваемые данные.
Нет сложных запросов. Redis не делает JOIN, GROUP BY, сложную фильтрацию. Он просто очень быстро находит данные по ключу.
Память конечна. Когда RAM заканчивается - Redis начинает удалять старые данные по политике вытеснения. Самая популярная - allkeys-lru: удаляет то что давно не использовалось.
Итог
Redis - это не просто кэш. Это швейцарский нож для быстрых данных. Кэширование, очереди, лидерборды, реальное время, сессии, ИИ-контекст - всё это Redis.
Я начал с простого: хранил текущий трек в Rockify. Потом добавил историю воспроизведения, счётчики, алгоритм ротации. Сейчас Redis - один из ключевых компонентов проекта.
Если ты ещё не используешь Redis - начни с SET и GET. Потом добавь TTL. Потом попробуй Hash для объектов. Остальное придёт само когда появится задача.

Комментарии