Backend Typescript 1.0.0 Help

Redis

Введение

Redis — это высокопроизводительное in-memory хранилище ключ-значение с поддержкой богатого набора структур данных: строки, хэши, списки, множества, отсортированные множества, битовые поля, гиперлоглоги, геоданные, стримы и др. Redis может работать как кэш, как брокер сообщений (через Pub/Sub), как быстрый индекс или как основная база для задач, где важны миллионы операций в секунду и низкие задержки.

  • Архитектура: однопоточный цикл событий с неблокирующими I/O, атомарность отдельных команд.

  • Скалирование: вертикально (CPU/ОЗУ), горизонтально через шардингRedis Cluster.

  • Отказоустойчивость: репликация, автоматическое переключение через Sentinel.

  • Долговечность: снимки RDB, журнал AOF, комбинированные режимы, настройки персистентности.

Когда и зачем использовать Redis

  • Кэш перед БД: снижает нагрузку на основную СУБД, ускоряет ответы.

  • Сессии и токены: хранение короткоживущих данных с TTL.

  • Очереди и события: через LPUSH/BRPOP, Streams и Pub/Sub.

  • Рейтинг/лидерборды: ZADD/ZRANGE по скору.

  • Счётчики и квоты: атомарные INCR, INCRBY, скользящие окна.

  • Geo-поиск: GEOADD, GEORADIUS.

Базовые концепции и модели данных

  • Ключи: бинарно-безопасные строки, рекомендуются префиксы (app:users:123).

  • Строки: до 512 МБ; поддержка битовых операций и инкрементов.

  • Хэши: компактное хранение полей объекта (HSET/HGETALL).

  • Списки: двусторонние очереди (LPUSH/RPUSH/BLPOP).

  • Множества: уникальные элементы, операции теории множеств (SADD/SMEMBERS).

  • Отсортированные множества: элементы с числовым скором для ранжирования (ZADD/ZREVRANGE).

  • Streams: лог записей с идентификаторами; потребительские группы.

  • TTL: истечение ключей (EXPIRE/PEXPIRE), пассивное и активное удаление.

Установка и запуск (локально)

# Mac (Homebrew) brew install redis brew services start redis # Debian/Ubuntu sudo apt-get update sudo apt-get install -y redis sudo systemctl enable --now redis # Docker docker run -p 6379:6379 --name redis redis:7-alpine

Ключевые команды (быстрый справочник)

  • Строки: SET key val EX 60, GET key, INCR cnt

  • Хэши: HSET user:1 name "Ann" age 30, HGETALL user:1

  • Списки: LPUSH q task1, BRPOP q 0

  • Множества: SADD tags red blue, SINTER a b

  • Отсортированные множества: ZADD board 100 user1, ZREVRANGE board 0 9 WITHSCORES

  • Streams: XADD mystream * field1 val1, XREAD COUNT 10 STREAMS mystream 0-0

  • Ключи и TTL: EXPIRE key 60, TTL key, DEL key

  • Транзакции: MULTI... EXEC, WATCH

  • Скрипты: EVAL, EVALSHA

Java: Lettuce (рекомендуется) и Jedis (популярно)

Пример на Lettuce (асинхронный/реактивный клиент). Покажем базовые операции, транзакции, Pub/Sub.

<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.3.1.RELEASE</version> </dependency>
import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; public class RedisLettuceExample { public static void main(String[] args) throws Exception { RedisURI uri = RedisURI.Builder.redis("localhost", 6379) //.withPassword("secret".toCharArray()) .build(); RedisClient client = RedisClient.create(uri); // Синхронные команды try (StatefulRedisConnection<String, String> conn = client.connect()) { RedisCommands<String, String> cmd = conn.sync(); cmd.setex("app:sess:123", 60, "user=42"); String v = cmd.get("app:sess:123"); System.out.println("GET: " + v); // демонстрация // Транзакция cmd.multi(); cmd.incr("counter"); cmd.incrby("counter", 5); cmd.exec(); System.out.println("Counter=" + cmd.get("counter")); } client.shutdown(); } }

Go: go-redis v9

Go-клиент redis/go-redis поддерживает кластеры, Sentinel, контекст, пайплайнинг и транзакции.

go get github.com/redis/go-redis/v9
package main import ( "context" "fmt" "time" "github.com/redis/go-redis/v9" ) var ctx = context.Background() func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", // Password: "secret", DB: 0, }) defer rdb.Close() // SET/GET + TTL if err := rdb.Set(ctx, "app:sess:123", "user=42", 60*time.Second).Err(); err != nil { panic(err) } v, _ := rdb.Get(ctx, "app:sess:123").Result() fmt.Println("GET:", v) // демонстрация }

TypeScript/Node.js: ioredis (или node-redis)

ioredis стабилен, поддерживает кластер, Sentinel, пайплайны и скрипты. Ниже — базовые операции, Pub/Sub, Lua.

npm i ioredis
import Redis from "ioredis"; async function main() { const redis = new Redis({ host: "127.0.0.1", port: 6379, // password: "secret", // lazyConnect: true, }); // SET с TTL, GET await redis.set("app:sess:123", "user=42", "EX", 60); const val = await redis.get("app:sess:123"); console.log("GET", val); // демонстрация await redis.quit(); } main().catch(console.error);

TTL, эвикции и политика памяти

Память в Redis конечна (maxmemory). При переполнении включается политика удаления: noeviction, allkeys-lru, allkeys-lfu, volatile-lru, volatile-ttl и др. Ключи с TTL могут удаляться проактивно (active expire) и при обращении (lazy expire).

Персистентность: RDB/AOF и производительность

  • RDB: периодические снимки (быстрый рестарт, меньше размер, риск потери последних секунд/минут).

  • AOF: журнал всех операций (минимальная потеря, больше размер, периодическая компрессия BGREWRITEAOF).

  • Смешанный режим: оптимальный баланс старта, размера и надёжности.

Репликация, Sentinel и Cluster

  • Репликация: replicaof host port, чтение с реплик (beware eventual consistency).

  • Sentinel: мониторинг мастера, автоматическое переключение на реплику, выдача адреса мастера клиентам.

  • Cluster: горизонтальное масштабирование, 16384 хэш-слотов, редиректы MOVED/ASK, шардирование по ключам.

Транзакции, скрипты и атомарность

Команды Redis атомарны; батчи через MULTI/EXEC исполняются последовательно. Для условных апдейтов используйте WATCH (оптимистическая блокировка). Сложную бизнес-логику можно перенести в Lua-скрипты (EVAL), чтобы выполнить серию операций атомарно на сервере.

# Пример с WATCH WATCH user:42:balance val = GET user:42:balance # если достаточно средств -> MULTI ... DECRBY ... EXEC

Паттерны использования и лучшие практики

  • Именование ключей: префиксы по доменам (app:module:entity:id), единый регистр, документируйте схемы.

  • Кэш-стратегии: cache-aside (сперва БД → кэш), write-through, write-behind; выбирайте с учётом консистентности/нагрузки.

  • Избегайте горячих ключей: распределяйте нагрузку (shardId в ключе), используйте батчи/пайплайны.

  • Обсервабилити: INFO, MONITOR, экспортеры Prometheus, трейсинг клиентов.

  • Безопасность: аутентификация, ACL, защищённая сеть, TLS, firewall; не выставляйте Redis в интернет.

Примеры шаблонов задач

  • Rate limiting: счётчики с TTL или Lua со скользящим окном.

  • Лидерборды: ZADD + ZRANGE/ZREVRANGE по очкам.

  • Очереди: списки с BRPOPLPUSH для «надёжного» потребления или Streams с группами.

  • Сеансы: SETEX и ротация ключей, вторичная индексация по пользователю (множества/хэши).

Last modified: 01 October 2025