Программа курса

Модуль 05 / Урок 20 из 27

Redis Cluster и хеш-слоты

Теория и практика

Когда данные или трафик не влезают в один инстанс, включается кластер: данные шардируются по узлам автоматически, но по особым правилам, которые надо знать клиенту.

Хеш-слоты

Пространство ключей разделено на 16384 слота. Слот ключа: CRC16(key) mod 16384. Каждый узел владеет диапазонами слотов; ключи, попавшие в один слот, живут на одном узле.

CLUSTER KEYSLOT user:1001
(integer) 5724
CLUSTER SLOTS          # карта: какие диапазоны слотов на каких узлах
CLUSTER INFO / CLUSTER NODES

Хеш-теги: управление размещением

Только часть ключа в фигурных скобках участвует в хешировании. Это способ положить связанные ключи на один узел:

user:{1001}:profile    # слот считается по "1001"
user:{1001}:cart
# Оба ключа в одном слоте → транзакция/Lua по ним возможна
⚠️ Хеш-тегами легко перераспределить нагрузку неравномерно: тег {tenant} на крупного клиента соберёт половину трафика на один узел. Тегируйте по мелким идентификаторам, а не по крупным сущностям.

Модель клиента

  • Подключение — к любому узлу; запрос не на свой слот → ответ -MOVED 5724 10.0.0.2:6379. Умные клиенты кэшируют карту слотов и ходят сразу куда надо (ошибка MOVED — сигнал обновить карту);
  • -ASK — временный редирект при миграции слота: сначала ASKING на целевой узел, потом команда;
  • Мульти-DB нет: только DB 0 (см. урок 1.2);
  • Мультиключевые команды — только в пределах одного слота; CROSSSLOT-ошибка иначе;
  • Транзакции/Lua — тоже в пределах одного слота.

Поднять кластер

# 3 мастера + 3 реплики одной командой (для обучения)
redis-cli --cluster create \
  127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
  127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
  --cluster-replicas 1

# Проверка и балансировка
redis-cli --cluster check 127.0.0.1:7000
redis-cli --cluster rebalance 127.0.0.1:7000

Resharding без даунтайма

Слоты переносятся между узлами по ключам:

redis-cli --cluster reshard 127.0.0.1:7000
# → сколько слотов, откуда, куда; во время переноса ключи
# блокируются короткими паузами (MIGRATE), клиенты получают ASK
  • Добавление узла — cluster meet + перенос слотов;
  • Удаление — перенос всех слотов с узла, затем выведение;
  • Миграция big key (миллионы элементов) — медленная: чистите большие ключи до resharing (урок 5.4).

Альтернативы кластеру

ВариантКакМинусы
Клиентский шардингconsistent hashing в приложении по N инстансамнет автоматического failover, рехешинг руками
ПроксиEnvoy/Predixy перед кластером+1 hop, минус «умные» фичи клиента
Вертикальный ростбольше RAM/CPU + IO-threadsупирается в одно ядро на исполнение команд
Разделение по назначениюотдельные инстансы: кеш / очереди / сессиибольше инстансов, но простейший путь

Частая недооценённая опция — разделение по назначению: кеш-инстанс и очередь-инстанс почти никогда не должны делить память и аварии.

Практика

  1. Поднимите 6-узловой кластер (docker-compose), разложите 100k ключей, проверьте распределение по узлам (DBSIZE на каждом).
  2. Найдите не-умный клиент: выполните GET ключа на «чужом» узле и прочитайте MOVED; затем сделайте то же клиентом с поддержкой кластера.
  3. Сломайте мультиключевую операцию (MGET двух ключей из разных слотов), почините хеш-тегами.
  4. Перенесите 100 слотов (--cluster reshard) под нагрузкой benchmark'а и оцените деградацию латентности.
Мини-квиз

1. Сколько слотов и зачем именно так? — 16384: компактная карта слотов помещается в heartbeat-сообщения между узлами.

2. Почему транзакция по user:1 и order:2 в кластере невозможна? — Разные слоты = разные узлы; атомарность на нескольких узлах не поддерживается.

3. MOVED vs ASK? — MOVED — постоянное размещение (обнови карту), ASK — временная ситуация миграции (одноразовый redirect).