← Назад к вопросам

Как происходит маршрутизация между выбором ноды в Redis?

2.7 Senior🔥 121 комментариев
#Архитектура и паттерны#Базы данных (NoSQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Маршрутизация между нодами в Redis Cluster

Maршрутизация в Redis — это процесс направления запроса к правильной ноде кластера на основе ключа. Это критически важно для распределённых систем.

Hash Slot вычисление

Редис использует CRC16 хеширование для определения, к какому слоту относится ключ:

import crc16

def get_hash_slot(key: str) -> int:
    # Если в ключе есть {}, используется часть между ними
    if "{" in key and "}" in key:
        hash_key = key[key.index("{") + 1:key.index("}")]
    else:
        hash_key = key
    
    # CRC16 модульная арифметика
    slot = crc16(hash_key.encode()) % 16384
    return slot

# Примеры
print(get_hash_slot("user:123"))      # определённый слот
print(get_hash_slot("order:{123}"))   # слот зависит только от 123

Фазы маршрутизации

1. Определение слота

  • CRC16 хеш ключа modulo 16384 (всего 16384 слота)
  • Диапазон: 0-16383

2. Поиск владельца слота

  • Клиент знает таблицу распределения слотов (slot → node)
  • Обновляется через CLUSTER SLOTS команду

3. MOVED редирект Если нода не владеет слотом:

# Redis вернёт:
# MOVED 5798 127.0.0.1:6380

# Клиент должен:
# 1. Обновить таблицу маршрутизации
# 2. Переслать запрос на 127.0.0.1:6380

ASK редирект (при миграции)

Во время миграции слота от ноды А к ноде В:

# Нода В ещё не владеет слотом официально, но может принять:
ASK 5798 127.0.0.1:6381

# Клиент должен:
# 1. Выполнить ASKING на целевой ноде
# 2. Затем отправить команду

connection.execute_command("ASKING")
result = connection.execute_command("GET", "key")

Практическое использование с redis-py

from redis.cluster import RedisCluster

# Автоматическая маршрутизация
rc = RedisCluster(startup_nodes=[
    {"host": "127.0.0.1", "port": 6379},
    {"host": "127.0.0.1", "port": 6380},
    {"host": "127.0.0.1", "port": 6381},
])

# Библиотека автоматически:
# 1. Вычисляет хеш слот
# 2. Находит ноду
# 3. Отправляет запрос
# 4. Обрабатывает MOVED/ASK редиректы
# 5. Обновляет таблицу маршрутизации

rc.set("user:123", "John")  # Маршрутируется на нужную ноду
value = rc.get("user:123")

Оптимизация маршрутизации

Pipeline для множественных ключей:

pipe = rc.pipeline()
for user_id in range(1000):
    pipe.get(f"user:{user_id}")
results = pipe.execute()

Hash Tag для группировки:

# Все эти ключи будут на одной ноде
rc.set("user:{account1}:name", "Alice")
rc.set("user:{account1}:email", "alice@example.com")
rc.set("order:{account1}:total", 1000)

# Они все в одном слоте благодаря {account1}

Потенциальные проблемы

Кольцевые редиректы: Если топология нарушена, возможны бесконечные MOVED

Неактуальная таблица маршрутизации: При быстром масштабировании клиент может отстать

Горячие ключи: Один слот может быть на критически нагруженной ноде

Ключевые моменты

  • Redis использует консистентное хеширование с фиксированным числом слотов
  • Маршрутизация происходит на уровне клиента (не на уровне сервера)
  • MOVED указывает на постоянный переход, ASK — на временную миграцию
  • Hash Tag позволяет группировать ключи для транзакций
  • Современные клиенты (redis-py, StackExchange.Redis) автоматически обрабатывают редиректы
Как происходит маршрутизация между выбором ноды в Redis? | PrepBro