Раздел 37 · Redis с нуля

Redis в продакшене: масштабирование и эксплуатация

junior~20 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

В прошлом уроке мы окинули взглядом специальные структуры Redis. Прежде чем разбирать их по одной, поднимем голову от команд. До сих пор у нас был один сервер на ноутбуке. Магазин уже держит в Redis кэш книг, корзины, сессии и очередь писем. Что будет, если этот сервер выключится, если данным станет тесно в памяти или если к нему подключится кто-то чужой? Этот урок обзорный: он показывает карту, а подробные уроки про каждую часть ждут в конце раздела.

Магазин с одним продавцом

Представь книжный магазин, где работает один продавец. Пока он на месте, всё хорошо. Заболел, и магазин закрыт. Это первая беда: одна точка отказа.

Хозяин нанимает помощника, который стоит рядом и запоминает каждую продажу. Если продавец заболел, помощник встаёт за кассу. Но кто решит, что продавец действительно заболел, а не вышел на минуту? Нужен управляющий, который следит за обоими и, если надо, назначает нового продавца.

Магазин растёт, и одному продавцу уже не справиться с очередью, а книги не помещаются на полки. Тогда открывают несколько отделов: художественная литература в одном, учебники в другом, и у каждого свой продавец.

У Redis те же три шага: реплика как помощник, Sentinel как управляющий и Cluster как отделы.

Реплика: копия на случай беды

Основной сервер называют master, копию replica. Реплику запускают с указанием, с кого копировать. Вот два контейнера на одной сети Docker, второй следит за первым:

docker network create shop
docker run -d --name redis-main --network shop redis:7
docker run -d --name redis-replica --network shop redis:7 redis-server --replicaof redis-main 6379

Первые секунды после старта реплика скачивает у основного сервера все данные, потом получает изменения по мере записи. Пишем в основной, читаем с реплики:

$ docker exec -it redis-main redis-cli SET book:1:title "Master and Margarita"
OK
$ docker exec -it redis-replica redis-cli GET book:1:title
"Master and Margarita"
$ docker exec -it redis-replica redis-cli SET book:1:title x
(error) READONLY You can't write against a read only replica.

Реплика получила ключ почти сразу, а писать в неё нельзя. Все записи идут в основной сервер, а читать можно с любого. Команда ROLE подскажет, кто есть кто:

127.0.0.1:6379> ROLE
1) "slave"
2) "redis-main"
3) (integer) 6379
4) "connected"
5) (integer) 178

Это ответ реплики: «я копия, мой основной сервер redis-main на порту 6379, связь есть». Последнее число показывает, сколько байт изменений реплика уже получила. Слово slave осталось в ответах Redis с давних времён, в документации теперь пишут replica.

Важная деталь: репликация в Redis асинхронная. Основной сервер отвечает OK, не дожидаясь реплик. Если он упал через миллисекунду после записи, реплика могла её не получить. Для кэша это не страшно, а для денег Redis главным хранилищем не делают, мы говорили об этом в первом уроке.

Реплика также не заменяет бэкап. Команда FLUSHALL, случайно выполненная на основном сервере, тут же очистит и реплику. Сохранение на диск разобрано в уроке про RDB и AOF.

Sentinel: кто назначит нового главного

Реплика есть, но если основной сервер упал, сама она главной не станет. Кто-то должен заметить падение и переключить приложение на реплику. Это и делает Sentinel: три или больше процессов-наблюдателей, которые раз в секунду проверяют серверы. Когда большинство наблюдателей согласны, что основной сервер не отвечает, они выбирают реплику и делают её основной. Это называется переключением при отказе.

Приложение при этом спрашивает адрес основного сервера не у себя в конфиге, а у Sentinel. Клиенты вроде node-redis умеют это сами. Наблюдателей должно быть нечётное число от трёх: так они не разделятся пополам в споре, жив сервер или нет.

урок из курса

Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.