← Назад к вопросам
Как происходит маршрутизация между выбором ноды в 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) автоматически обрабатывают редиректы