До сих пор Redis хранил данные: строки, списки, кэш. В прошлом уроке мы закончили защищать кэш. Теперь новая роль: Redis как почтальон между частями приложения. Покупатель оформил заказ, и об этом должны узнать сразу несколько сервисов: отправка писем, склад, панель менеджера. Для такой рассылки в Redis есть Pub/Sub.
Радио
Представь радиостанцию. Ведущий говорит в микрофон и не знает, кто его слушает: сто человек, тысяча или никто. Слушатель настраивает приёмник на частоту и слышит всё, что звучит в эфире, пока приёмник включён. Если ты включил радио в 9:05, новости в 9:00 ты пропустил, записи эфира нет.
Pub/Sub в Redis работает так же. Издатель отправляет сообщение в канал, Redis тут же раздаёт копии всем, кто сейчас подписан. Издатель ничего не знает о подписчиках, подписчики ничего не знают об издателе.
Подписаться и опубликовать
Нужны два терминала. В первом сервис писем подписывается на канал orders:new:
127.0.0.1:6379> SUBSCRIBE orders:new
1) "subscribe"
2) "orders:new"
3) (integer) 1
Reading messages... (press Ctrl-C to quit or any key to type command)
Redis подтвердил подписку тремя строками: что сделано, на какой канал и на сколько каналов этот клиент теперь подписан. Дальше redis-cli ждёт сообщений. Соединение перешло в режим подписчика: обычные команды вроде GET в нём не работают, только команды подписки и PING.
Во втором терминале магазин публикует событие командой PUBLISH:
127.0.0.1:6379> PUBLISH orders:new order:16
(integer) 1
Ответ 1 значит «сообщение получил один подписчик». А в первом терминале появилось:
1) "message"
2) "orders:new"
3) "order:16"
Тип события, канал и само сообщение. Сообщение это обычная строка, часто в неё кладут JSON с подробностями заказа.
Нет слушателя, нет сообщения
Опубликуем в канал, где никого нет:
127.0.0.1:6379> PUBLISH orders:paid order:16
(integer) 0
Ноль получателей, и сообщение исчезло. Redis его нигде не сохранил. Если подписчик подключится через секунду, этого сообщения он не увидит. Такую доставку называют «отправил и забыл».
Отсюда ограничения, которые важно запомнить:
- сервис писем перезапускался 10 секунд, и все заказы за это время он пропустил;
- подписчик упал посреди обработки, повторно сообщение не придёт;
- медленный подписчик, который не успевает читать, Redis в итоге отключит, чтобы не копить его сообщения в памяти.
Поэтому Pub/Sub хорош для событий, которые не жалко потерять: «обнови страницу», «у товара сменилась цена, перерисуй», уведомление в чат поддержки, сброс локального кэша на всех серверах. Если каждое сообщение важно, нужна очередь, которая хранит сообщения. О ней следующий урок.
урок из курса
Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.