Перейти к основному содержимому

3.06. Справочник по Redis

Разработчику Аналитику Тестировщику
Архитектору Инженеру

Справочник по Redis

Строки (String)

Строка в Redis — это произвольная последовательность байтов, ограниченная 512 МБ. Это наиболее универсальный и часто используемый тип. Строка может содержать текст, сериализованный объект (например, JSON или Protocol Buffers), base64-кодированное изображение, бинарный идентификатор, числовое значение в текстовом виде и даже битовую карту.

Команды, непосредственно работающие со строками:

  • SET key value [EX seconds | PX milliseconds] [NX | XX] [KEEPTTL] — устанавливает значение ключа. Опция NX гарантирует установку только если ключ отсутствует (аналог INSERT), XX — только если ключ уже существует (аналог UPDATE). EX/PX задают время жизни (TTL). KEEPTTL сохраняет существующий TTL при перезаписи.
  • GET key — возвращает значение или nil, если ключ не существует.
  • GETRANGE key start end — возвращает подстроку (или подпоследовательность байтов) по индексам включительно. Индексация с нуля; поддерживает отрицательные индексы (с конца строки).
  • SETRANGE key offset value — заменяет часть строки, начиная с указанного offset, на value. Если строка короче — дополняется нулевыми байтами.
  • MGET key [key …], MSET key value [key value …], MSETNX key value [key value …] — массовые операции чтения/записи. MSETNX атомарно устанавливает все пары только если ни один из ключей не существует.
  • STRLEN key — возвращает длину значения в байтах.
  • APPEND key value — дописывает value в конец строки и возвращает новую длину.

Числовые операции над строками (строка должна быть представлена числом, целым или с плавающей точкой; в противном случае — ошибка):

  • INCR key, INCRBY key increment, INCRBYFLOAT key increment — атомарно увеличивают значение на 1, на increment (целое) или на increment (дробное). Возвращают новое значение.
  • DECR key, DECRBY key decrement — аналогично уменьшают.
  • GETSET key value — атомарно устанавливает новое значение и возвращает предыдущее. Полезна для реализации токенов, счётчиков с историей.

Битовые операции (строка рассматривается как массив битов; порядок байтов — от старшего к младшему внутри байта, байты — последовательно):

  • SETBIT key offset value — устанавливает бит по абсолютному смещению offset (0 — первый бит). Возвращает предыдущее значение бита.
  • GETBIT key offset — возвращает значение бита (0 или 1).
  • BITCOUNT key [start end] — подсчитывает количество установленных битов в строке. Если заданы start и end — в указанном диапазоне байтов (не битов!).
  • BITPOS key bit [start] [end] — находит позицию первого бита, равного bit (0 или 1).
  • BITOP operation destkey key [key …] — выполняет побитовую операцию (AND, OR, XOR, NOT) над строками и сохраняет результат в destkey. Для NOT допускается один источник.

Внутреннее представление (encoding):

  • embstr — компактная структура для строк длиной ≤ 44 байт (в Redis 7); аллоцируется одним блоком, неделимая (immutable).
  • raw — динамическая строка (sds — Simple Dynamic String), используется для более длинных значений или после модификации строки, изначально в embstr.
  • При числовых операциях (INCR и т.д.) Redis не хранит отдельно «числовой тип» — значение остаётся строкой, но парсится/форматируется как число при выполнении команды.

Хэши (Hash)

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

Команды:

  • HSET key field value [field value …] — устанавливает одно или несколько полей. Возвращает число новых полей (не общее количество обновлённых).
  • HGET key field — возвращает значение поля или nil.
  • HMGET key field [field …] — массовое чтение полей.
  • HGETALL key — возвращает все поля и значения (в виде чередующегося списка).
  • HDEL key field [field …] — удаляет указанные поля. Возвращает число удалённых.
  • HEXISTS key field — проверяет существование поля (1/0).
  • HLEN key — количество полей.
  • HKEYS key, HVALS key — возвращают все поля или все значения соответственно.
  • HINCRBY key field increment, HINCRBYFLOAT key field increment — числовые операции над полем.
  • HSTRLEN key field — длина значения конкретного поля в байтах.

Особенности:
Поля и значения — это строки (как в String). Нет вложенных хэшей: для иерархии требуется использовать составные имена полей (profile.name, profile.age) или выносить вложенные объекты в отдельные ключи.

Внутреннее представление:

  • ziplist — компактный список пар значений (поле, значение), используется при малом количестве полей (по умолчанию ≤ 512) и коротких строках (по умолчанию ≤ 64 байта на элемент).
  • listpack — начиная с Redis 7.0, ziplist заменён на listpack, который безопаснее при параллельных изменениях и потребляет меньше памяти.
  • hashtable — хэш-таблица на основе dict (сам Redis использует её глобально), применяется при превышении лимитов ziplist/listpack.

Списки (List)

Список — упорядоченная коллекция строк, поддерживающая вставку и извлечение с обоих концов. Реализован как двусвязный список, однако при малом размере может использовать listpack для экономии памяти.

Команды:

  • LPUSH key value [value …], RPUSH key value [value …] — добавление в начало/конец. Возвращают длину списка после операции.
  • LPOP key [count], RPOP key [count] — извлечение из начала/конца. Без count — один элемент; с count — до count элементов (если доступно меньше — возвращаются все).
  • BLPOP key [key …] timeout, BRPOP — блокирующие аналоги: если все списки пусты, клиент ждёт появления элемента или таймаута. Возвращают имя первого непустого ключа и значение. Критически важны для блокирующих очередей.
  • LINDEX key index — получение элемента по индексу (0 — первый, -1 — последний).
  • LSET key index value — установка значения по индексу (ошибка, если индекс вне диапазона).
  • LLEN key — длина списка.
  • LRANGE key start stop — срез (включительно); поддерживает отрицательные индексы.
  • LTRIM key start stop — обрезка до указанного диапазона.
  • LINSERT key BEFORE|AFTER pivot value — вставка перед/после первого вхождения pivot.

Особенности:
Списки не поддерживают произвольную вставку в середину с линейной сложностью — LINSERT ищет pivot линейно. При больших списках (>10k элементов) такие операции нежелательны.

Внутреннее представление:

  • listpack — используется, если количество элементов ≤ list-max-listpack-size (по умолчанию −2, что означает размер ≤ 8 КБ) и list-compress-depth = 0 (без сжатия).
  • linkedlist — двусвязный список узлов, применяемый при превышении лимитов listpack или при включённом сжатии (для экономии памяти при частых LPOP/RPOP).

Множества (Set)

Множество — неупорядоченная коллекция уникальных строк. Гарантирует отсутствие дубликатов и поддерживает классические операции теории множеств: объединение, пересечение, разность.

Основные команды:

  • SADD key member [member …] — добавляет один или несколько элементов. Возвращает число новых элементов.
  • SREM key member [member …] — удаляет указанные элементы. Возвращает число удалённых.
  • SMEMBERS key — возвращает все элементы множества (в неопределённом порядке).
  • SCARD key — мощность множества (число элементов).
  • SISMEMBER key member — проверяет принадлежность элемента (1/0).
  • SRANDMEMBER key [count] — возвращает count случайных элементов без удаления. При count > 0 — возможны повторы; при count < 0 — гарантированно |count| элементов (с повторами, если |count| > SCARD).
  • SPOP key [count] — удаляет и возвращает count случайных элементов (по умолчанию 1).
  • SMOVE source destination member — атомарно перемещает элемент из source в destination.

Операции над несколькими множествами:

  • SINTER key [key …] — пересечение.
  • SUNION key [key …] — объединение.
  • SDIFF key [key …] — разность: элементы из первого множества, отсутствующие в остальных.
  • SINTERSTORE destination key [key …] и аналоги SUNIONSTORE, SDIFFSTORE — сохраняют результат в destination.

Особенности:

  • Отсутствие порядка означает, что SMEMBERS может возвращать элементы в разном порядке при повторных вызовах (хотя на практике часто стабилен, пока не происходят рехэширования).
  • Нет прямой поддержки частичного поиска (LIKE, PREFIX), так как хранение осуществляется в хэш-таблице (для произвольного доступа) или intset (для малых целых).

Внутреннее представление (encoding):

  • intset — компактный массив 16/32/64-битных знаковых целых, используется, если все элементы являются целыми в диапазоне, умещающемся в 64 бита, и их количество ≤ set-max-intset-entries (по умолчанию 512).
  • hashtable — хэш-таблица (dict), применяется иначе. Потребляет больше памяти, но обеспечивает O(1) для большинства операций.

Упорядоченные множества (Sorted Set, ZSET)

Упорядоченное множество — коллекция уникальных строк (элементов), каждому из которых сопоставлён числовой score (вещественное число двойной точности). Элементы автоматически упорядочены по score (по возрастанию), при равных score — лексикографически по элементу.

Ключевые команды:

  • ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member …]
    • NX: добавить только новые элементы.
    • XX: обновлять только существующие.
    • GT: обновлять только если новый score больше текущего.
    • LT: только если меньше.
    • CH: возвращать число изменённых элементов (по умолчанию возвращается число новых добавленных).
    • INCR: вести себя как ZINCRBY для одного элемента (атомарное увеличение score).
  • ZREM key member [member …] — удаление элементов.
  • ZSCORE key member — возвращает score элемента или nil.
  • ZCARD key — количество элементов.
  • ZCOUNT key min max — число элементов в диапазоне score (включительно; -inf, +inf допустимы).
  • ZRANK key member, ZREVRANK key member — позиция элемента (с 0) в порядке сортировки по возрастанию/убыванию.

Чтение по диапазону:

  • ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
    • start, stop — индексы (по умолчанию), score-границы (BYSCORE) или лексикографические (BYLEX).
    • REV — обратный порядок.
    • WITHSCORES — включает score в ответ.
  • ZREVRANGEZRANGE … REV.
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] — устаревшая форма, эквивалентна ZRANGE … BYSCORE.
  • ZRANGESTORE dst src min max [BYSCORE | BYLEX] [REV] [LIMIT offset count] — сохраняет результат диапазона в новое ZSET (Redis 6.2+).

Модификация по диапазону:

  • ZREMRANGEBYRANK key start stop — удаление по рангу.
  • ZREMRANGEBYSCORE key min max — по score.
  • ZREMRANGEBYLEX key min max — по лексикографическому диапазону (требует одинакового score у всех элементов).

Арифметические операции:

  • ZINCRBY key increment member — атомарное изменение score.
  • ZUNIONSTORE, ZINTERSTORE, ZDIFFSTORE — объединение, пересечение, разность нескольких ZSET с возможностью задания весов и агрегатных функций (SUM (по умолчанию), MIN, MAX).
    В Redis 6.2+ появились неразрушающие аналоги: ZUNION, ZINTER, ZDIFF (без сохранения).

Лексикографическая сортировка (BYLEX):
Требует, чтобы у всех элементов был одинаковый score (обычно 0). Диапазоны задаются как [string, (string, +, -. Полезна для реализации словарей или индексов по префиксам.

Внутреннее представление (encoding):

  • listpack — для малых ZSET (по умолчанию ≤ 128 элементов и длина всех строк ≤ 64 байт). Сортировка происходит при каждом запросе ZRANGE, но потребление памяти минимально.
  • skiplist — комбинация skip list (для O(log N) поиска по score и рангу) и хэш-таблицы (для O(1) поиска по элементу). Применяется при превышении лимитов listpack. Это основная production-структура.

Битовые карты (Bitmaps)

Bitmaps — не отдельный тип данных, а семантика, наложенная на строки. Строка рассматривается как массив битов (до 2³² бит = 512 МБ). Используется для компактного хранения флагов: посещение пользователя за день, статус задачи, availability и т.д.

Команды уже перечислены в разделе String, но ключевые паттерны:

  • Ежедневная активность: SETBIT user:123:20251121 1440 1 — пользователь 123 в 24:00 (1440-я минута) дня 2025-11-21 был активен.
  • Аналитика за период: BITCOUNT user:123:20251101 0 -1 — активность за день; BITOP AND result u:123:d1 u:123:d2 … — пересечение дней.
  • Поиск первого нуля/единицы: BITPOS key 0 — позиция первого неактивного слота (полезно для распределения ресурсов).

Ограничения:

  • Максимальное смещение — 2³² − 1 (4 294 967 295 бит ≈ 512 МБ).
  • Нет встроенной поддержки сжатия (но listpack может частично компенсировать это при записи последовательных нулей).
  • При чтении больших участков эффективнее использовать GETRANGE + обработку на клиенте.

HyperLogLog

Вероятностная структура для оценки мощности множества (количества уникальных элементов). Погрешность ~0.81 %, потребление памяти — фиксированные ~12 КБ независимо от объёма данных.

Команды:

  • PFADD key element [element …] — добавление элементов (возвращает 1, если внутреннее состояние изменилось; 0 — иначе).
  • PFCOUNT key [key …] — оценка количества уникальных элементов. Для нескольких ключей — оценка объединения.
  • PFMERGE destkey sourcekey [sourcekey …] — объединение двух или более HLL в один.

Особенности:

  • Элементы не хранятся — только хэши и счётчики.
  • Идеально для аналитики: DAU, MAU, уникальные посетители, уникальные IP за период.
  • Не поддерживает удаление элементов.
  • Повторные PFADD одного и того же элемента не влияют на результат.

Внутреннее представление:

  • Фиксированный заголовок + массив 16384 6-битных регистров (всего 12288 байт = 12 КБ).

Геоиндексы (GEO)

Реализованы поверх ZSET: координаты (широта, долгота) кодируются в 52-битное целое (геохэш), хранятся как score, имя объекта — как member.

Команды:

  • GEOADD key longitude latitude member [longitude latitude member …] — добавление точек. Возвращает число новых элементов.
  • GEOPOS key member [member …] — возвращает координаты (в виде [lon, lat]).
  • GEODIST key member1 member2 [m|km|ft|mi] — расстояние между двумя точками.
  • GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] — поиск точек в радиусе.
  • GEORADIUSBYMEMBER key member radius … — то же, но относительно существующего элемента.

Особенности:

  • Точность геохэша ограничена ~0.6 метра (для широт/долгот в пределах Земли).
  • Не поддерживаются геометрические операции (полигоны, линии) — только точки и окружности.
  • STORE сохраняет результат как ZSET (для последующей обработки), STOREDIST — как ZSET с расстоянием в качестве score.

Stream

Лог-ориентированная структура: неизменяемые записи с уникальными идентификаторами (ID), упорядоченные по времени. Аналог Kafka-lite внутри Redis.

Команды записи:

  • XADD key [NOMKSTREAM] [MAXLEN [=|~] N] [LIMIT N] ID field value [field value …]
    • ID обычно * (автогенерация: timestamp-sequence).
    • MAXLEN ~ N — приблизительное ограничение длины (с отложенной усечкой); MAXLEN = N — строгое, дорогое.
    • NOMKSTREAM — не создаёт поток, если его нет.

Чтение:

  • XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key …] ID [ID …] — чтение с указанных ID ($ — только новые записи). Блокирующий режим (BLOCK) делает его пригодным для push-подписок.
  • XRANGE key start end [COUNT count], XREVRANGE — не блокирующее чтение по диапазону ID.

Группы потребителей (consumer groups):
Позволяют реализовать конкурентное потребление с подтверждением обработки (acknowledgement), как в RabbitMQ/Kafka.

  • XGROUP CREATE key groupname id-or-$ [MKSTREAM] — создаёт группу.
  • XREADGROUP GROUP group consumer [COUNT n] [BLOCK ms] STREAMS key >> означает «не прочитанные этой группой».
  • XACK key group ID [ID …] — подтверждение обработки.
  • XPENDING key group [ID-start ID-end] [COUNT n] — просмотр "зависших" сообщений.
  • XCLAIM, XAUTOCLAIM — переназначение зависших сообщений другому потребителю.

Особенности:

  • ID имеют формат timestamp-sequence, монотонно возрастают даже при коррекции системного времени (Redis использует логическое время).
  • Поддерживает метки (MKSTREAM, ENTRIESREAD в Redis 7), но без встроенных retention policy (только MAXLEN).
  • Максимальная длина записи — 2³² − 1 байт; поток в целом может быть сколь угодно большим (ограничено памятью).

JSON (RedisJSON — модуль, но де-факто стандарт)

Позволяет хранить, запрашивать и изменять JSON-документы напрямую. Требует загрузки модуля ReJSON или использование Redis Stack.

Основные команды:

  • JSON.SET key path value [NX|XX] — запись JSON-значения по пути ($ — корень).
  • JSON.GET key [INDENT str] [NEWLINE str] [SPACE str] [path …] — получение подмножества; форматирование — для отладки.
  • JSON.DEL key path — удаление по пути.
  • JSON.TYPE key path, JSON.STRLEN key path, JSON.ARRLEN key path, JSON.OBJLEN key path — интроспекция.
  • JSON.NUMINCRBY key path number, JSON.NUMMULTBY — арифметика над числами.
  • JSON.ARRAPPEND key path value [value …], JSON.ARRINSERT, JSON.ARRPOP, JSON.ARRTRIM — манипуляции с массивами.
  • JSON.OBJKEYS key path, JSON.OBJDEL key path — работа с объектами.

Пути (JSONPath-подобные):

  • $.user.name — вложенное поле.
  • $[*].score — все score в массиве.
  • $[?(@.age > 30)] — фильтрация (частично поддерживается).
  • $..name — рекурсивный спуск (не во всех версиях).

Особенности:

  • Внутреннее представление — двоичное дерево (не строка), что ускоряет доступ к полям.
  • Не совместим с обычными Redis-командами (GET, SET выдадут ошибку на ключ JSON).
  • Индексация отдельно — через RedisSearch.

Конфигурация Redis (redis.conf): ключевые параметры для production

Конфигурационный файл Redis — redis.conf — содержит более 250 директив. Ниже перечислены только те, от которых напрямую зависят стабильность, безопасность и предсказуемость поведения в production-среде. Все остальные параметры (например, loglevel, pidfile, tcp-backlog) имеют второстепенное значение при корректной инфраструктурной обвязке.

Память и управление ресурсами

  • maxmemory <bytes>обязательный параметр в режиме кэширования. Указывает максимальный объём памяти, который может использовать Redis (в байтах; допустимы суффиксы mb, gb). По умолчанию — 0 (неограниченная память), что ведёт к OOM-kill в Linux при нехватке RAM.
  • maxmemory-policy <policy> — стратегия вытеснения при достижении maxmemory. Варианты:
    • noeviction — новые записи отклоняются с ошибкой (режим «база данных»).
    • allkeys-lru — вытесняет наименее недавно используемые ключи (универсально для кэша).
    • allkeys-lfu — наименее часто используемые (требует Redis 4.0+; лучше для long-tail распределений).
    • volatile-lru, volatile-lfu, volatile-ttl, volatile-random — вытесняют только ключи с TTL. Используются, если часть данных должна храниться вечно (например, сессии), а часть — временно (кэш страниц).
    • allkeys-random — случайный выбор (только для тестов).
  • maxmemory-samples <count> — число ключей, проверяемых при LRU/LFU (по умолчанию 5). Увеличение до 10–20 повышает точность, но снижает производительность на 5–10 %.

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

  • save <seconds> <changes> — правила снапшотирования RDB. Например:
    save 900 1 — сохранить, если ≥1 запись за 900 секунд;
    save 300 10 — ≥10 записей за 300 секунд;
    save 60 10000 — ≥10 000 записей за 60 секунд.
    Удаление всех save отключает RDB.

  • stop-writes-on-bgsave-error yes — останавливает запись, если фоновый bgsave завершился с ошибкой (например, не хватает места на диске). Включать обязательно.

  • rdbcompression yes — сжатие RDB-файла (LZF). Незначительно снижает скорость записи, но экономит место.

  • rdbchecksum yes — добавление CRC64 в конец RDB для проверки целостности (рекомендуется).

  • dbfilename dump.rdb, dir ./ — имя и каталог для RDB-файла.

  • appendonly yes — включение AOF.

  • appendfilename "appendonly.aof" — имя файла.

  • appendfsync everysecоптимальный компромисс между надёжностью и производительностью. Другие варианты:

    • always — синхронизация после каждой команды (максимальная надёжность, ≤ 1 000 ops/s);
    • no — синхронизация по решению ОС (максимальная производительность, риск потери нескольких секунд).
  • no-appendfsync-on-rewrite yes — отключает fsync во время BGREWRITEAOF, чтобы не блокировать основной процесс.

  • auto-aof-rewrite-percentage 100, auto-aof-rewrite-min-size 64mb — условия автоматического переписывания AOF: если размер вырос на 100 % по сравнению с последним переписанным и превышает 64 МБ.

Репликация

  • replicaof <masterip> <masterport> — (устаревшее slaveof) указывает, от кого реплицировать данные. В кластере управляется автоматически.
  • replica-serve-stale-data yes — если связь с мастером потеряна, реплика продолжает отдавать старые данные (иначе возвращает ошибку).
  • replica-read-only yes — реплика принимает только команды чтения (строго соблюдать в production).
  • repl-diskless-sync no — передача RDB-дампа по сети напрямую, без записи на диск реплики (актуально для SSD-мастеров и медленных дисков реплик).
  • repl-timeout 60 — таймаут репликации (должен быть > repl-ping-replica-period).
  • requirepass <password>устаревший способ аутентификации реплик; в Redis 6+ использовать ACL.

Кластеризация

  • cluster-enabled yes — включение режима кластера.
  • cluster-config-file nodes.conf — файл состояния кластера (не редактировать вручную).
  • cluster-node-timeout 15000 — время в миллисекундах, после которого узел считается недоступным (влияет на failover).
  • cluster-replica-validity-factor 10 — множитель cluster-node-timeout, в течение которого реплика считается актуальной для выборов мастера.
  • cluster-migration-barrier 1 — минимальное количество реплик у мастера, при котором реплика может мигрировать для балансировки.

Безопасность и сетевые параметры

  • bind 127.0.0.1 -::1 — привязка к localhost (IPv4 и IPv6). Для production в доверенной сети — внутренний IP (10.0.0.5); никогда не 0.0.0.0 без фаервола.
  • protected-mode yes — блокирует доступ без пароля или bind, если Redis слушает на публичном интерфейсе. Оставлять включённым.
  • port 6379 — порт. Можно менять для изоляции (например, 6380 для stage).
  • tcp-keepalive 300 — интервал keepalive в секундах (0 — отключено).
  • timeout 0 — время неактивности соединения до разрыва (0 — неограниченно). В высоконагруженных системах лучше 300–600.
  • tls-port 0, tls-cert-file, tls-key-file, tls-ca-cert-file — параметры TLS (актуальны с Redis 6.0+). Обязательны при передаче по ненадёжным сетям.

ACL (Access Control Lists) — управление доступом

Начиная с Redis 6.0, requirepass и rename-command устарели в пользу ACL. Политика задаётся в redis.conf или динамически через ACL SETUSER.

Синтаксис ACL

user <username> [<rule> ...]

Правила бывают:

  • Аутентификация:
    • on / off — включить/выключить пользователя.
    • >password, #hash — задать пароль в открытом виде или SHA256-хэш.
    • (>p1 >p2) — несколько паролей.
  • Команды:
    • +command, -command — разрешить/запретить конкретную команду.
    • +@category, -@category — категория: @keyspace, @read, @write, @admin, @dangerous, @connection и т.д.
    • allcommands, nocommands — полный доступ или запрет.
  • Ключи:
    • ~pattern — разрешить доступ к ключам по шаблону (*, cache:*, user:*:*).
    • allkeys, resetkeys — все ключи или очистить список разрешений.
  • Pub/Sub:
    • &pattern — разрешить подписку на каналы (&*, &events.*).
    • allchannels, resetchannels.

Примеры

  • Администратор:
    user admin on >s3cr3t ~* &* +@all
  • Кэш-сервис (только чтение/запись в cache:*, без опасных команд):
    user cache on >pwd ~cache:* +@read +@write -@dangerous
  • Мониторинг (только INFO, PING, CLIENT LIST):
    user monitor on >mon ~* +info +ping +client|list -@all
    (обратите внимание: client|list — синтаксис для команд с вертикальной чертой в названии).

Команды управления:

  • ACL LIST — список пользователей и их прав.
  • ACL USERS — имена пользователей.
  • ACL CAT — список категорий.
  • ACL WHOAMI — текущий пользователь.
  • ACL LOG [count] — журнал нарушений ACL (важно для аудита).

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

INFO [section]

Возвращает структурированную информацию. Ключевые секции:

  • server — версия, режим (standalone/cluster), порты, PID.
  • clientsconnected_clients, blocked_clients, client_recent_max_input_buffer.
  • memoryused_memory, used_memory_rss, mem_fragmentation_ratio, maxmemory, evicted_keys.
  • persistence — статус RDB/AOF (rdb_last_bgsave_status, aof_enabled, aof_current_size).
  • statstotal_commands_processed, instantaneous_ops_per_sec, keyspace_hits/misses, rejected_connections.
  • replicationrole, connected_slaves, master_sync_in_progress, slave_repl_offset.
  • cpuused_cpu_sys, used_cpu_user.
  • commandstats — статистика по каждой команде (calls, usec, usec_per_call).
  • clustercluster_enabled, cluster_state (ok/fail), cluster_slots_assigned.
  • keyspace — количество ключей по БД (db0:keys=123,expires=45,avg_ttl=123456).

CLIENT LIST

Возвращает список всех подключений:
id=123 addr=10.0.0.5:54321 fd=12 name=app age=123 idle=45 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=get

  • idle — время бездействия в секундах (полезно для поиска «забытых» соединений).
  • qbuf, qbuf-free — размер входного буфера (нарастание qbuf — признак медленного клиента).
  • omem — память, выделенная под выходной буфер (высокое значение — backpressure).

SLOWLOG

  • SLOWLOG GET [n] — список медленных команд (порог задаётся в slowlog-log-slower-than, по умолчанию 10 000 мкс = 10 мс).
  • Каждая запись содержит: ID, timestamp, duration (мкс), команда, клиент.
  • Используется для поиска «тяжёлых» KEYS *, SMEMBERS, ZRANGE без LIMIT.

LATENCY

  • LATENCY LATEST — последние события задержек (fork, aof_fsync_always, command).
  • LATENCY HISTORY <event> — история по событию (до 160 точек).
  • LATENCY GRAPH <event> — ASCII-график задержек.
  • LATENCY RESET — очистка истории.

Транзакции, pipeline и Lua-скрипты

MULTI / EXEC

  • MULTI — начало транзакции: команды ставятся в очередь.
  • Команды внутри MULTI не выполняются сразу, но проверяются на синтаксис.
  • EXEC — атомарное выполнение очереди.
  • Нет отката (rollback): если команда внутри EXEC завершается ошибкой (например, INCR на строке), остальные команды всё равно выполняются.
  • DISCARD — отмена очереди.
  • WATCH key [key …] — оптимистичная блокировка: если любой из key изменён до EXEC, транзакция отклоняется (EXEC возвращает nil).

Ограничения:

  • Не заменяет транзакции в реляционных СУБД.
  • Не обеспечивает изоляцию: между WATCH и EXEC могут выполняться другие команды от других клиентов.
  • Для сложной логики предпочтительны Lua-скрипты.

Pipeline

  • Группировка нескольких команд в один TCP-пакет для уменьшения сетевых round-trip time (RTT).
  • Не атомарен и не требует MULTI.
  • Пример в redis-cli:
    (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
  • Все клиентские библиотеки (ioredis, redis-py, Lettuce) поддерживают pipeline API.
  • Максимальный выигрыш — при большом числе мелких команд (например, 1000 INCR → 100× ускорение за счёт устранения RTT).

Lua-скрипты (EVAL, EVALSHA)

  • Выполняются атомарно: пока скрипт работает, другие команды не выполняются.
  • Язык — Lua 5.1; стандартная библиотека ограничена (нет os, io, loadfile).
  • Доступ к Redis через redis.call('CMD', ...) (ошибки прерывают скрипт) или redis.pcall (возвращают nil + ошибку).
  • Скрипты кэшируются по SHA1-хэшу: SCRIPT LOADEVALSHA.

Ключевые сценарии:

  • Rate limiting («слепой счётчик»):
    local key = KEYS[1]
    local limit = tonumber(ARGV[1])
    local window = tonumber(ARGV[2])
    redis.call('INCR', key)
    redis.call('EXPIRE', key, window)
    return redis.call('GET', key) <= limit
  • Распределённая блокировка (Redlock-подобная):
    if redis.call('SET', KEYS[1], ARGV[1], 'NX', 'PX', ARGV[2]) then
    return 1
    else
    return 0
    end
  • Атомарное обновление ZSET + кэша.

Ограничения:

  • Скрипты должны быть короткими (< 5 мс), иначе блокируют весь сервер.
  • Нельзя вызывать случайные функции (math.random запрещён; использовать redis.sha1hex() как seed).
  • В кластере все ключи в KEYS должны принадлежать одному слоту.

Кластеризация и репликация: детали реализации и поведения

Распределение ключей: хэш-слоты (hash slots)

Redis Cluster делит пространство ключей на 16384 хэш-слота. Каждый ключ K привязывается к слоту по формуле:

slot = CRC16(K) mod 16384

CRC16 вычисляется только по части ключа до первого { — это позволяет использовать хэш-теги:

  • user:1000:profile и user:1000:sessions → разные слоты;
  • user:{1000}:profile и user:{1000}:sessions → один и тот же слот (только 1000 участвует в хэшировании).
    Это критически важно для операций, требующих атомарности над несколькими ключами (например, транзакции в Lua-скриптах или MGET/MSET в кластере).

Каждый узел кластера отвечает за подмножество слотов. В отказоустойчивом кластере каждый слот обслуживается одним мастером и ≥1 репликой.

Протокол взаимодействия: gossip и команды кластера

Кластер использует два канала связи:

  • Порт данных (по умолчанию 6379) — клиентские команды и кросс-нодовая пересылка данных.
  • Порт кластера (6379 + 10000 = 16379) — gossip-трафик: обмен heartbeat, обнаружение отказов, перераспределение слотов.

Команды управления кластером (выполняются на ноде):

  • CLUSTER NODES — состояние всех нод (ID, роль, слоты, флаги master, slave, fail?, handshake).
  • CLUSTER SLOTS — отображение слотов → ноды (удобно для клиентов при инициализации).
  • CLUSTER INFO — глобальное состояние (cluster_state:ok, cluster_slots_assigned, cluster_known_nodes).
  • CLUSTER KEYSLOT key — вычисление слота для ключа.
  • CLUSTER COUNTKEYSINSLOT slot — число ключей в слоте (только на мастере для этого слота).
  • CLUSTER GETKEYSINSLOT slot count — имена ключей (только для отладки — не использовать в production!).

Обработка запросов в кластере

Клиент должен поддерживать cluster-aware поведение. При запросе к неверной ноде возвращаются специальные ошибки:

  • -MOVED <slot> <ip>:<port> — постоянное перенаправление (клиент должен обновить кэш маршрутизации).
  • -ASK <slot> <ip>:<port> — временное перенаправление при миграции слота (клиент должен сделать ASKING, затем повторить команду).

Алгоритм миграции слота (CLUSTER SETSLOT <slot> IMPORTING <source-node-id> / MIGRATING):

  1. Источник помечает слот как MIGRATING; цель — как IMPORTING.
  2. На запрос к ключу в этом слоте:
    • если ключ есть на источнике — обрабатывается;
    • если нет — возвращается ASK на цель.
  3. Администратор вызывает MIGRATE для порционной пересылки ключей.
  4. После полной миграции обе ноды выполняют CLUSTER SETSLOT <slot> NODE <new-master-id>.

Отказоустойчивость в кластере

Failover происходит автоматически, если:

  • мастер недоступен (не отвечает на gossip в течение cluster-node-timeout, по умолчанию 15 с);
  • ≥ половина реплик мастера (включая саму реплику-инициатора) согласны с отказом (cluster-replica-validity-factor × cluster-node-timeout);
  • кворум нод в кластере жив (cluster-require-full-coverage yes — по умолчанию, требует покрытия всех слотов).

Реплика с наибольшим replica-priority (по умолчанию 100; 0 — не участвует в выборах) и наибольшим replication offset (актуальность данных) становится мастером.


Redis Sentinel: альтернативная модель отказоустойчивости

Sentinel — отдельный процесс (демон), предназначенный для мониторинга и автоматического переключения в standalone- или master-replica-топологиях (без кластеризации).

Архитектура

  • Минимум 3 Sentinel-ноды (для избежания split-brain).
  • Каждый Sentinel:
    • проверяет доступность мастера через PING;
    • обменивается информацией с другими Sentinel через gossip (__sentinel__:hello канал);
    • запоминает историю отказов.
  • При обнаружении отказа:
    1. sdown (subjectively down) — одна нода считает мастер недоступным.
    2. odown (objectively down) — кворум Sentinel соглашается.
    3. Выбор новой реплики (по replica-priority, replication offset, runid).
    4. SLAVEOF NO ONE на выбранной реплике.
    5. SLAVEOF <new-master> на остальных репликах.
    6. Обновление конфигурации в sentinel.conf.
    7. Отправка нотификаций (+switch-master, +slave-reconf-done).

Конфигурация Sentinel (sentinel.conf)

sentinel monitor mymaster 10.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster secret
  • 2 — кворум для объявления odown.
  • down-after-milliseconds — таймаут для sdown (должен быть < failover-timeout).
  • parallel-syncs — сколько реплик могут синхронизироваться с новым мастером одновременно (рекомендуется 1 при больших данных).

Ограничения Sentinel:

  • Не масштабирует данные — только обеспечивает отказоустойчивость для одного master-replica набора.
  • Требует внешнего балансировщика или клиентской логики (redis-py имеет Sentinel-класс).
  • Медленнее кластера в отказоустойчивости (failover ~30–60 с против ~15–30 с в кластере).

Redis Stack: модули как стандарт де-факто

Redis Stack — сборка от Redis Inc., включающая ядро Redis и пять ключевых модулей. Все они open-source, но официально поддерживаются только в Redis Enterprise или Redis Stack.

RedisJSON

Уже описан в предыдущей части. Дополнительно:

  • Поддерживает JSON Schema (валидация при JSON.SET).
  • Встроенный индекс для полей (через RediSearch).
  • Совместим с redis-cli --json.

RediSearch

Полнотекстовый движок с поддержкой:

  • Инвертированных индексов.
  • Точного совпадения, префиксов, нечёткого поиска (FUZZY), фонетического (SOUNDEX).
  • Сортировки, агрегации, геофильтров.
  • Индексации полей из Hash, JSON, даже строк (через токенизацию).

Базовые команды:

  • FT.CREATE idx ON HASH|JSON SCHEMA field1 TAG field2 TEXT ...
  • FT.SEARCH idx "@field1:{tag} @field2:hello~"
  • FT.AGGREGATE idx "*" GROUPBY 1 @field1 REDUCE COUNT 0 AS count

RedisBloom

Набор вероятностных структур:

  • Bloom Filter — проверка на принадлежность (ложноположительные допустимы, ложноотрицательных нет):
    BF.ADD users 1001, BF.EXISTS users 1001
  • Cuckoo Filter — аналог Bloom, но с поддержкой удаления.
  • Count-Min Sketch — оценка частоты элементов:
    CMS.INCRBY traffic google.com 100, CMS.QUERY traffic google.com
  • Top-K — приближённый список самых частых элементов.

RedisTimeSeries

Оптимизирован для хранения временных рядов:

  • Компактное хранение (дельта-кодирование, сжатие).
  • Агрегация «на лету» (avg, sum, min, max, range, count, first, last, std.p, std.s, var.p, var.s).
  • Downsampling (автоматическое создание агрегированных рядов).

Команды:

  • TS.CREATE sensor:123 RETENTION 86400 LABELS type temperature
  • TS.ADD sensor:123 * 25.3
  • TS.RANGE sensor:123 - + AGGREGATION avg 60000

RedisAI

Выполнение моделей машинного обучения внутри Redis:

  • Поддержка TensorFlow, PyTorch, ONNX, TFLite.
  • Кэширование входных/выходных тензоров.
  • Конвейеры (AI.DAGRUN для нескольких моделей последовательно).

Пример:

AI.MODELSTORE mymodel TF CPU INPUTS 1 input OUTPUTS 1 output BLOB ...
AI.TENSORSET input FLOAT 1 784 VALUES 0.1 0.2 ...
AI.MODELRUN mymodel INPUTS input OUTPUTS output
AI.TENSORGET output VALUES

Интеграция с облаками и Kubernetes

Облачные managed-сервисы

ПлатформаСервисОсобенности
AWSAmazon ElastiCache for RedisПоддержка Cluster Mode, TLS, AUTH, backup/restore, auto-failover, integration with CloudWatch. Не поддерживает модули (RedisJSON и др.).
AzureAzure Cache for RedisPremium-tier — кластеризация, persistence, disaster recovery (geo-replication). Поддержка Redis 6/7, но без модулей.
GCPMemorystore for RedisТолько standalone и replication; кластеризация доступна в Memorystore Enterprise (на базе Redis Enterprise).
Redis Inc.Redis CloudПолная поддержка Redis Stack, Active-Active Geo-Distribution, TLS, ACL, backup, auto-scaling.

Kubernetes

  • Официальный Helm-чарт: redis/redis (standalone/replica) и redis/redis-cluster.
  • Операторы:
    • Redis Enterprise Operator (Redis Inc.) — для управления Redis Enterprise в K8s.
    • Open Source Redis Operator (OT-CONTAINER-KIT) — community-driven.
  • Рекомендации:
    • Использовать StatefulSet для нод с персистентностью.
    • Выделять отдельные PersistentVolume для dir и appendonlydir.
    • Настроить readinessProbe/livenessProbe через redis-cli ping.
    • Использовать headless service для gossip-трафика в кластере.

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

  1. Хранение больших значений (> 1 МБ)
    — приводит к задержкам из-за блокировки основного потока при сетевой передаче или дампинге.
    — решение: фрагментация (user:1000:profile:1, :2, …) или вынос в объектное хранилище (S3) с хранением ссылки в Redis.

  2. Монолитные JSON-объекты без структурирования
    JSON.SET user:1000 $ '{...огромный_объект...}' → при каждом обновлении поля перезаписывается весь объект.
    — решение: хранить поля отдельно в Hash или использовать JSON.SET user:1000 $.name "John".

  3. Использование KEYS * в production
    — O(N) по всем ключам, блокирует сервер на десятки мс/сек.
    — решение: использовать Scan-итераторы (SCAN 0 MATCH user:* COUNT 1000), либо вести отдельные индексы (Sets/ZSets).

  4. Отсутствие TTL на временных данных
    — «утечка» памяти: сессии, кэши, временные токены накапливаются.
    — решение: всегда указывать EX/PX в SET, использовать EXPIRE после операций.

  5. Неконтролируемый рост Sorted Set
    ZADD logs * "$timestamp $message" без усечения → потребление памяти растёт линейно.
    — решение: ZREMRANGEBYRANK logs 0 -10001 после добавления или использовать Streams с MAXLEN.

  6. Отказ от ACL в пользу requirepass
    — один пароль для всех — нарушение принципа минимальных привилегий.
    — решение: создать пользователей app:cache, app:sessions, monitor с разными правами.

  7. Репликация без repl-diskless-sync на SSD-мастерах
    — при синхронизации реплика пишет RDB на диск → I/O contention.
    — решение: включить repl-diskless-sync yes, если реплики — на HDD или сетевые тома.

  8. Кластер без хэш-тегов для связанных данных
    MGET user:1000:name user:1000:age-CROSSSLOT ошибка.
    — решение: использовать user:{1000}:name, user:{1000}:age.