Перейти к содержанию

Redis

Раздел 02 · Механизмы · Сравнения

Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.

Область версий: Redis Open Source 7.4; документация latest, без Redis 8-only функций. Проверка источников: 2026-11-02.

1. Архитектура и модель данных

FACT. In-memory key-value сервер со strings, hashes, lists, sets, sorted sets, streams, bitmaps и probabilistic structures. Команды выполняются последовательно относительно других команд на основном command execution path; фоновые потоки и I/O не превращают скрипт в параллельную транзакцию. Тип структуры определяет память и доступ: ZSET подходит для ordered time window, HLL даёт приближённую cardinality, не список уникальных платежей.

flowchart LR
  Client --> Primary[Primary commands or Lua]
  Primary --> RAM[In-memory structures]
  Primary --> AOF[Configured AOF or RDB persistence]
  Primary -. async .-> Replica

2. Физическое хранение и путь записи

Данные живут в памяти, внутренние encodings зависят от типа/размера. RDB создаёт snapshot; fork и copy-on-write при интенсивной записи увеличивают потребление памяти. AOF журналирует команды; fsync policy определяет окно потери при crash. Rewrite AOF не равен резервной копии. Одновременные persistence, replica sync и eviction конкурируют за RAM/CPU/I/O.

Источники механизма: документация 3.

3. Индексы и путь чтения

Основной доступ по key; HASH field и ZSET score/member — собственные структуры, а не произвольные SQL-индексы. SCAN не обеспечивает snapshot и может повторять keys; KEYS блокирует command processing на большой базе. Большой ZSET или hash может стать hot key: Cluster делит keys, не элементы одной структуры.

Источники механизма: документация 5.

4. Транзакции и consistency guarantees

INCR атомарен относительно других команд; клиентский GET→SET теряет обновления. MULTI/EXEC выполняет очередь без interleaving, но не обеспечивает rollback: runtime error одной команды не отменяет остальные. WATCH даёт optimistic CAS и требует retry при abort; это не snapshot isolation.

Lua также изолирован от interleaving, но ошибка после записи не откатывает уже сделанные изменения. Валидировать аргументы и типы до mutation; ограничивать время скрипта. Atomicity не равна durability: результат может быть утрачен при async replica failover даже после локального успешного ответа.

Источники механизма: документация 1, документация 2, документация 4.

5. Репликация, partitioning и sharding

Обычная replication асинхронна; Sentinel обеспечивает detection/failover, но не consensus по каждому подтверждённому write. WAIT запрашивает replica acknowledgements и не превращает Redis в strongly consistent CP store. Cluster распределяет keys по hash slots; {account:42} hash tag группирует связанные keys. Multi-key commands/scripts должны иметь keys одного slot; resharding требует cluster-aware клиента и обработки MOVED/ASK.

Источники механизма: документация 4, документация 5.

6. Конкурентная запись и конфликты

WATCH/CAS полезен для конкурентной версии, Lua — для read/check/write одного ограниченного набора keys. Уникальный event_id в ZSET обеспечивает dedup только пока member сохранён. Истёкшая dedup запись не защищает от старого replay. На горячем финансовом счёте redis lock без fencing не защищает PostgreSQL от приостановленного владельца lease.

Источники механизма: документация 2, документация 5.

7. Отказы и восстановление

После crash загрузка RDB/AOF возвращает только сохранённые данные; повреждённый/обрезанный журнал требует штатных процедур и проверки последствий. После потери Redis cache восстанавливается из source of truth; одновременно ограничить cache stampede. Для antifraud сначала восстановить Flink state и offsets, затем versioned features, либо выполнять контролируемый warm-up с явной политикой решений при неполном окне.

Источники механизма: документация 3, документация 4.

8. Масштабирование и ограничения

Scale-up ограничен RAM и одним горячим key/скриптом; Cluster масштабирует независимые keys. Большие значения, массовое истечение TTL и blocking commands создают задержки соседним запросам. Для приблизительных global counters можно распределить shards и суммировать, но жёсткий глобальный лимит при этом требует координации.

9. Performance trade-offs

Cache-aside: чтение miss→DB→cache; запись DB→invalidate. Гонка старого reader с invalidation может положить устаревшее значение: versioned values, ограниченный TTL или сериализация нужны по требованиям. TTL ограничивает срок жизни, eviction освобождает память по policy; cache miss не доказывает отсутствия бизнес-объекта. Для durable coordination обычно выбирать noeviction и обрабатывать write errors, но это само по себе не создаёт финансовую надёжность.

10. Мониторинг и эксплуатация

INFO memory/persistence/replication/stats, SLOWLOG, LATENCY DOCTOR и cluster state; отслеживать used_memory/RSS, fragmentation, evicted_keys, expired_keys, rejected_connections, replication backlog и AOF rewrite. Проверять latency во время fork/rewrite и failover. Не выгружать содержимое чувствительных keys в общедоступные логи. Размер структуры и hot-key distribution важнее среднего ops/sec.

11. Сценарии FinTech и iGaming

INFERENCE. Cache профиля/лимитов, rate limiting, sliding windows, низколатентные antifraud features. Redis может хранить materialized state, восстанавливаемый из Kafka/Flink. Команда списания денег должна проверять authoritative ledger: сетевой split, eviction и async failover не должны менять финансовый факт.

12. Когда не выбирать

Не выбирать финансовым source of truth только потому, что INCR атомарен. Для irrecoverable balances нужны модель durability, reconciliation, audit, fencing и доказанное восстановление; простой Redis counter этого не предоставляет. Не хранить бесконечную историю events без расчёта памяти и retention.

13. Вопросы на собеседовании

Почему Lua не гарантирует exactly-once? Клиент может потерять ответ и повторить команду, а state/offset не связаны общей транзакцией.

Чем TTL отличается от eviction? TTL — заданное истечение key, eviction — удаление при memory pressure; оба дают miss, но по разным причинам.

Что сломает hot key в Cluster? Один key остаётся на одном primary; добавленные узлы его command path не распараллелят.

14. Практические SQL/config примеры

sliding-window.lua — atomic admission counter с server time, bounded retention и duplicate retry; feature-upsert.lua — versioned state projection. Проверены синтаксис и ограниченные model tests Lua; настоящий Redis 7.4/Cluster, failover и persistence не запущены. Walkthrough объясняет границы восстановления.

15. Дополнительные источники

Политика версий и ограничений: реестр.

Типичные ошибки проектирования

Приравнивать Lua к rollback/durability; не ограничивать ZSET; смешивать TTL и idempotency horizon; обещать финансовую точность после async failover.

Практические упражнения

Разберите timeout сразу после Lua: повторите тот же ID, затем дождитесь окончания retention. Зафиксируйте, где dedup перестала действовать и почему.