lenec ru

← все посты

Redis cluster vs Sentinel: выбираем стратегию высокой доступности

18K

Redis из коробки не имеет встроенной отказоустойчивости. Sentinel и Cluster решают эту проблему по-разному: Sentinel обеспечивает автоматический failover для одного мастера, Cluster — шардирование данных с встроенной репликацией. Разберёмся, когда какой подход выбрать.

Sentinel: автоматический failover и кворум

Redis Sentinel — отдельный процесс, который мониторит master-replica топологию и переключает мастер при падении. Минимум 3 Sentinel-инстанса для кворума:

# sentinel.conf
sentinel monitor mymaster 10.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

Как работает failover:

  • Sentinel пингует мастер каждую секунду. Нет ответа down-after-milliseconds — SDOWN
  • Кворум (2 из 3) согласны — ODOWN (objective down)
  • Лидер промоутит реплику в мастер, остальные переключаются
  • Клиенты получают уведомление через +switch-master

Sentinel не шардирует данные. Все данные на одном мастере, реплики — для чтения и failover.

Cluster: шардирование по hash slots

Redis Cluster делит keyspace на 16384 hash slots. Каждый мастер владеет частью слотов. Ключ попадает в слот: CRC16(key) % 16384:

# Создать кластер: 3 master + 3 replica
redis-cli --cluster create \
  10.0.0.1:6379 10.0.0.2:6379 10.0.0.3:6379 \
  10.0.0.4:6379 10.0.0.5:6379 10.0.0.6:6379 \
  --cluster-replicas 1

# Проверить распределение слотов
redis-cli --cluster check 10.0.0.1:6379

# Resharding: перенести слоты между нодами
redis-cli --cluster reshard 10.0.0.1:6379

При падении мастера его реплика автоматически промоутится — без внешнего Sentinel.

Сравнение: когда Sentinel, когда Cluster

+---------------------+------------------+--------------------+
| Критерий            | Sentinel         | Cluster            |
+---------------------+------------------+--------------------+
| Шардирование        | нет              | 16384 hash slots   |
| Макс. данных        | RAM одной ноды   | сумма всех нод     |
| Failover            | внешний процесс  | встроенный         |
| Multi-key операции  | без ограничений  | только в одном slot|
| Минимум нод         | 3 sentinel + 2   | 6 (3m + 3r)       |
+---------------------+------------------+--------------------+

Sentinel хватает: данные до 64-128 GB на одной ноде, нужен простой failover, используются multi-key операции (MGET, транзакции, Lua).

Cluster нужен: данные не помещаются на одну ноду, нужно горизонтальное масштабирование записи.

Клиентская сторона: ioredis

// Подключение через Sentinel
import Redis from 'ioredis';

const redis = new Redis({
  sentinels: [
    { host: '10.0.0.10', port: 26379 },
    { host: '10.0.0.11', port: 26379 },
    { host: '10.0.0.12', port: 26379 }
  ],
  name: 'mymaster',
  password: 'redis-pass'
});

// Подключение к Cluster
const cluster = new Redis.Cluster([
  { host: '10.0.0.1', port: 6379 },
  { host: '10.0.0.2', port: 6379 },
  { host: '10.0.0.3', port: 6379 }
], {
  redisOptions: { password: 'redis-pass' },
  scaleReads: 'slave'
});

ioredis автоматически обрабатывает MOVED и ASK redirects в Cluster-режиме.

Подводные камни

  • Split-brain в Sentinel — при сетевом разделении старый мастер продолжает принимать записи. После восстановления данные теряются. Защита: min-replicas-to-write 1
  • MOVED/ASK в Cluster — клиент без поддержки redirects получит ошибки. Используйте cluster-aware библиотеки
  • Multi-key ограниченияMGET key1 key2 работает только если оба ключа в одном слоте. Решение: hash tags — {user:1}:name и {user:1}:email попадут в один слот
  • Resharding под нагрузкой — перенос слотов создаёт нагрузку. Делайте в off-peak

Docker-compose для локального Sentinel

services:
  redis-master:
    image: redis:7-alpine
    command: redis-server --requirepass mypass
    ports: ["6379:6379"]

  redis-replica:
    image: redis:7-alpine
    command: redis-server --replicaof redis-master 6379 --masterauth mypass
    depends_on: [redis-master]

  sentinel:
    image: redis:7-alpine
    command: redis-sentinel /etc/sentinel.conf
    volumes: ["./sentinel.conf:/etc/sentinel.conf"]
    depends_on: [redis-master, redis-replica]

Для Cluster в Docker нужен --cluster-announce-ip на каждой ноде, иначе клиенты получат внутренние IP контейнеров.

Начните с Sentinel — он проще и покрывает 90% случаев. Переходите на Cluster когда данные не помещаются на одну ноду или нужна горизонтальная запись.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.