Redis cluster vs Sentinel: выбираем стратегию высокой доступности
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 когда данные не помещаются на одну ноду или нужна горизонтальная запись.