Ответ
В стандартном режиме Pub/Sub — нет, это механизм fire-and-forget без persistence. Если подписчик отключится, он потеряет сообщения, отправленные в период простоя.
Для гарантированной доставки в Redis используются Streams. Они позволяют:
- Хранить сообщения
- Организовывать consumer groups
- Подтверждать обработку (ack)
- Контролировать повторные доставки
Пример работы с Redis Streams на PHP (используя библиотеку phpredis):
// Продюсер добавляет сообщение в поток
$redis->xAdd('orders_stream', '*', ['user_id' => 123, 'status' => 'pending']);
// Консьюмер читает неподтверждённые сообщения из своей группы
$messages = $redis->xReadGroup(
'orders_group',
'consumer_1',
['orders_stream' => '>'],
1
);
// После успешной обработки сообщение подтверждается
if (processOrder($messages[0])) {
$redis->xAck('orders_stream', 'orders_group', [$messages[0]['id']]);
}
Таким образом, выбор между Pub/Sub и Streams зависит от требований к надёжности: Pub/Sub для событий в реальном времени, где потеря допустима; Streams — для критичных сообщений, которые должны быть обработаны гарантированно.
Ответ 18+ 🔞
А, ну это классика, блядь! Смотри, тут ситуация как с доставкой пиццы: можно крикнуть в окно «Пиццу привезите!» и надеяться, что кто-то услышит, а можно заказать по телефону и получить чек с номером заказа, чтобы потом не было «а мы не получали».
Стандартный Pub/Sub в Redis — это как тот крик в окно. Огненный механизм «отправил и забыл» (fire-and-forget), безо всякого persistence. Если твой подписчик в этот момент в туалете, спит или у него просто соединение отвалилось — всё, сообщения, которые летели, пока он был в отключке, канули в лету. Потерял, сука, и всё тут. Надежность — ноль ебать.
А вот если тебе нужна гарантированная доставка, чтобы ни одно сообщение не потерялось, даже если консьюмер на неделю в кому впал, то тут в игру вступают Streams. Это уже серьёзная тема, ёпта. Они умеют:
- Хранить сообщения, как в очереди.
- Организовывать consumer groups, чтобы несколько работяг одну очередь разгребали.
- Подтверждать обработку (ack) — типа «окей, я съел это сообщение, можно убирать со стола».
- Контролировать повторные доставки, если какой-то работяга взял сообщение и сдох, не обработав.
Вот, смотри, как это на PHP примерно выглядит (с phpredis):
// Продюсер (тот, кто создаёт заказы) пихает сообщение в поток. Звёздочка '*' — это «сгенерируй ID сам».
$redis->xAdd('orders_stream', '*', ['user_id' => 123, 'status' => 'pending']);
// Консьюмер (работяга) читает из своей группы. Знак '>' — это «давай мне то, что я ещё не брал».
$messages = $redis->xReadGroup(
'orders_group', // Название бригады
'consumer_1', // Имя конкретного работяги
['orders_stream' => '>'], // Откуда читать и что именно
1 // Сколько сообщений максимум взять за раз
);
// Допустим, обработал заказ...
if (processOrder($messages[0])) {
// ...тогда шлёт подтверждение: «Всё, братва, я справился, можете это дело удалять».
$redis->xAck('orders_stream', 'orders_group', [$messages[0]['id']]);
}
Короче, выбор, блядь, простой, как три копейки:
- Pub/Sub — для быстрых событий в реальном времени, типа нотификаций «пользователь онлайн», где потеря пары сообщений — да похуй, не критично.
- Streams — для критичных бизнес-сообщений, типа «спиши деньги со счёта» или «создай заказ». Тут уже потеря — это пиздец, волнение ебать, и нужно всё гарантированно доставить.
Всё, вопрос решён. Выбирай по обстоятельствам, а не потому что «о, а это модное слово».