Гарантирует ли Redis доставку сообщений?

Ответ

В стандартном режиме 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 — для критичных бизнес-сообщений, типа «спиши деньги со счёта» или «создай заказ». Тут уже потеря — это пиздец, волнение ебать, и нужно всё гарантированно доставить.

Всё, вопрос решён. Выбирай по обстоятельствам, а не потому что «о, а это модное слово».