Один сервер Redis перестаёт быть достаточным по двум причинам: данные не помещаются в память или простой узла останавливает сервис. Redis Cluster решает обе задачи: ключи распределяются по мастерам, а каждый мастер получает реплику. Цена — ограничения на операции с ключами и более сложная диагностика.

Как устроен Redis Cluster

Кластер делит пространство ключей на 16384 слота. Каждый мастер отвечает за свой набор слотов, а клиент по хешу ключа определяет, к какому узлу идти. Реплики копируют данные мастера и могут занять его место при отказе. Узлы общаются через служебный порт, который на 10000 больше основного: для порта 7001 это 17001.

Для отказоустойчивости нужен кворум мастеров. Кластер из трёх мастеров переживает отказ одного; при двух кворума нет и автоматическое восстановление невозможно. Минимальная схема — три мастера и три реплики на разных хостах с синхронизированным временем.

Подготовка узлов и конфигурация

Для лаборатории можно поднять несколько экземпляров на одной машине с разными портами, но в продакшене разносите их по хостам и зонам доступности. Ниже — типовой конфиг одного узла. Директория и файл журнала должны быть уникальны для каждого экземпляра.

# /etc/redis/redis-7001.conf
port 7001
bind 10.0.0.11 127.0.0.1
protected-mode yes
daemonize no
dir /var/lib/redis/7001
logfile /var/log/redis/7001.log

cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 5000
cluster-require-full-coverage yes

appendonly yes
appendfsync everysec
maxmemory-policy noeviction

Не ставьте политику allkeys-lru на узлы с данными, которые нельзя терять: Redis начнёт удалять ключи под давлением памяти. Для кластера важнее предсказуемость, поэтому noeviction и отдельный мониторинг. Пароль задавайте через ACL или requirepass вместе с masterauth, иначе реплика не подключится.

sudo systemctl start redis-server@7001
redis-cli -p 7001 ping
redis-cli -p 7001 info server | head -20

Если экземпляры запускаются не через systemd-шаблон, используйте свой unit. Главное — одинаковые параметры кластера и отдельные файлы состояния. Файл nodes-7001.conf нельзя копировать между узлами: каждый хранит там своё представление кластера.

Создание кластера

Когда все шесть узлов отвечают на ping, создайте кластер одной командой. Утилита распределит слоты и назначит реплики. Флаг —cluster-replicas 1 означает одну реплику на мастера. Для боевой схемы добавьте —cluster-yes, но только после проверки адресов.

redis-cli --cluster create \
  10.0.0.11:7001 10.0.0.12:7001 10.0.0.13:7001 \
  10.0.0.14:7001 10.0.0.15:7001 10.0.0.16:7001 \
  --cluster-replicas 1

После создания проверьте состояние. Команда cluster info показывает cluster_state:ok и число известных узлов. Команда cluster nodes перечисляет мастеров, реплики и диапазоны слотов. Если состояние fail, сначала смотрите сеть и журналы, а не пытайтесь сразу пересоздавать кластер.

redis-cli -c -p 7001 cluster info
redis-cli -c -p 7001 cluster nodes
redis-cli --cluster check 10.0.0.11:7001

Флаг -c включает перенаправление: если ключ принадлежит другому узлу, клиент сам перейдёт по MOVED. Без -c вы увидите ошибку MOVED и решите, что кластер сломан.

Ключи, слоты и хеш-теги

Ключи распределяются по слотам функцией CRC16. Обычно это удобно: нагрузка размазывается автоматически. Проблема в том, что операции с несколькими ключами должны попадать в один слот. MGET, MSET, транзакции и Lua-скрипты через разные слоты завершатся ошибкой CROSSSLOT.

Решение — хеш-тег: часть ключа в фигурных скобках. Всё, что внутри скобок, участвует в расчёте слота, остальное игнорируется. Так можно держать связанные данные рядом, не отказываясь от шардирования.

SET user:{42}:name "Anna"
SET user:{42}:email "anna@example.com"
MGET user:{42}:name user:{42}:email

# эти ключи, скорее всего, попадут в разные слоты
MGET user:42:name user:43:name

Не делайте хеш-тегом слишком общий идентификатор: если все ключи получат тег {app}, они окажутся в одном слоте и шардирование исчезнет. Тег должен отражать естественную группу.

Resharding и балансировка

Со временем данные растут неравномерно. Resharding переносит слоты с одного мастера на другой. Утилита спрашивает источник, приёмник и число слотов, затем переносит ключи. Rebalance выбирает узлы сам, но на нагруженном кластере делайте это в окно обслуживания.

redis-cli --cluster reshard 10.0.0.11:7001 \
  --cluster-from <source-node-id> \
  --cluster-to <target-node-id> \
  --cluster-slots 1000 \
  --cluster-yes

redis-cli --cluster rebalance 10.0.0.11:7001 \
  --cluster-use-empty-masters

После переноса проверьте cluster nodes и число ключей на каждом мастере через DBSIZE. Не ориентируйтесь только на слоты: один слот может содержать миллионы ключей. Перекос из-за горячего ключа resharding не исправит.

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

Реплика становится мастером, когда большинство мастеров теряет связь с этим мастером. По умолчанию cluster-node-timeout равен 15 секундам; в примере выше — 5, что ускоряет реакцию, но повышает риск ложного срабатывания. Оставьте значение по умолчанию до измерения задержек.

Проверку лучше делать в тестовом окружении. Остановите один мастер и наблюдайте, как реплика повышается, а клиенты переподключаются. Команда cluster failover на реплике запускает ручное переключение — это безопаснее аварии на боевом узле.

redis-cli -p 7002 cluster failover
redis-cli -c -p 7001 cluster info
redis-cli -c -p 7001 info replication
redis-cli --cluster check 10.0.0.11:7001

Вернувшийся узел должен стать репликой, а не вторым мастером. Если этого не произошло, проверьте журнал и состояние кластера. Не запускайте его с прежним файлом nodes: устаревшее представление о слотах создаст конфликт.

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

Следите за тремя группами показателей: состояние кластера, задержки и память. cluster info показывает cluster_state и число слотов, info replication — отставание реплик, info memory — расход памяти. Для задержек используйте LATENCY DOCTOR и SLOWLOG.

redis-cli -p 7001 info memory | grep -E "used_memory_human|mem_fragmentation_ratio"
redis-cli -p 7001 info replication
redis-cli -p 7001 slowlog get 10
redis-cli -p 7001 latency doctor

Резервное копирование в кластере — это снимки с каждого мастера, а не с одного узла. BGSAVE создаёт RDB-файл, который нужно скопировать в отдельное хранилище. Проверяйте восстановление на тестовом стенде.

Типичные ошибки

  • Кластер из двух мастеров: нет кворума для автоматического failover.
  • Использование SELECT с номером базы: в кластере доступна только база 0.
  • Мультиключевые команды без хеш-тега: ошибка CROSSSLOT.
  • Клиент без поддержки кластера: постоянные MOVED вместо работы.
  • Одинаковый файл nodes на нескольких узлах после клонирования.
  • Резервное копирование только с одного мастера.
  • Отсутствие мониторинга свободной памяти и отставания реплик.

Итог

Redis Cluster — это не «Redis, но быстрее», а распределённая система со своими правилами. Начните с трёх мастеров и трёх реплик, проверьте сеть и время, создайте кластер и прогоните тест отказа в лаборатории. Затем настройте мониторинг памяти и состояния слотов. Хеш-теги должны группировать связанные данные, но не превращать весь кластер в один слот.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте