Apache Kafka vs Streams и Pub/Sub в Redis

Kafka vs Redis Streams and Pub/Sub, обучение Apache Kafka, Apache Kafka для дата-инженеров и разработчиков, курсы по Apache Kafka, Apache Kafka разработчик примеры курсы обучение, Школа Больших Данных Учебный центр Коммерсант

Как key-value СУБД Redis может работать с потоковыми данными и чем Pub/Sub и Streams отличаются от Apache Kafka. Сравнение и рекомендации по использованию.

Потоковое сохранение данных Redis

Будучи очень быстрым key-value хранилищем, NoSQL-СУБД Redis часто используется в качестве слоя кэширования для разгрузки основной базы данных. В отличие от многих других key-value хранилищ, Redis поддерживает разные типы данных для значений. Одним из таких типов данных является Streams – структура данных, которая действует как журнал только для добавления и устраняет некоторые ограничения такого лога. В частности, сюда относятся произвольный доступ за время O(1) и сложные стратегии потребления для групп потребителей. Можно использовать потоки для записи и одновременного распространения событий в реальном времени, например, в следующих сценариях:

  • отслеживание действий пользователя, кликов и пр.;
  • мониторинг датчиков;
  • уведомления, например, сохранение записи уведомлений каждого пользователя в отдельном потоке.

Redis генерирует уникальный идентификатор для каждой записи потока, которые можно использовать для последующего получения связанных с ними записей или для чтения и обработки всех последующих записей в потоке. Потоки Redis поддерживают несколько стратегий обрезки (чтобы предотвратить неограниченный рост потоков) и более одной стратегии потребления. Поскольку идентификаторы потоков обычно короткие и имеют фиксированную длину, это фактически сводится к поиску с постоянным временем. Потоки реализованы как поразрядные деревья, поэтому Redis Streams обеспечивает высокоэффективную вставку и чтение данных.

Также в Redis есть каналы публикации/подписки, которые позволяют реализовать асинхронный обмен данными между продюсером и потребителем с гарантией доставки не более одного раза. Это означает, что сообщение будет доставлено один раз, если вообще будет. Как только сообщение будет отправлено сервером Redis, повторно оно отправлено не будет. Если потребитель не может обработать сообщение, например, из-за ошибки или отключения сети, эти данные потеряются навсегда.

Таким образом, между Redis Streams и Redis Pub/Sub есть следующие отличия:

  • Поток может иметь несколько клиентов (потребителей), ожидающих данных. Каждый новый элемент по умолчанию будет доставлен каждому потребителю, ожидающему данных в данном потоке. Такое поведение отличается от списков блокировки, где каждый потребитель получает отдельный элемент. Однако возможность распространения среди нескольких потребителей аналогична Pub/Sub.
  • В Pub/Sub сообщения отправляются и никогда не сохраняются, а при использовании списков блокировки, когда сообщение принимается клиентом, оно выталкивается, т.е. фактически удаляется из списка. Потоки работают принципиально по-другому. Все сообщения добавляются в поток на неопределенный срок, если пользователь явно не удаляет записи. Разные потребители знают, какое сообщение для него является новым, запоминая идентификатор последнего полученного сообщения.
  • Группы потребителей потоков обеспечивают уровень контроля, которого не могут достичь списки Pub/Sub или списки блокировки, с разными группами для одного и того же потока, явным подтверждением обработанных элементов, возможностью проверки ожидающих элементов, запросом необработанных сообщений и последовательной видимостью истории для каждого один клиент, который может видеть только свою личную историю сообщений.

Тип данных Redis Streams является более новым, чем тип данных Pub/Sub, и предназначен для поддержки отключенных распределенных потоковых приложений. Этот тип данных представляет собой структуру данных, доступную только для добавления, хранящуюся в памяти — в основном сохраняемые сообщения! А каналы Pub/Sub ориентированы только на доставку сообщений только подключенным в данный момент подписчикам, поскольку используется механизм доставки на основе push, и если текущих подключенных подписчиков нет, сообщения просто отбрасываются. Каналы не запоминают сообщения, но работают быстро.

Redis Streams хранит сообщения, даже если в данный момент нет подключенных потребителей, и даже после их успешной доставки, а также поддерживает блокировку потребителей, группы потребителей и включает новую операцию записи данных в потоки. Тип данных Streams также более сложен, чем значения канала Pub/Sub, которые представляют собой просто строки, поскольку записи потока состоят из набора из 1 или более пар значений поля. Записи потока также строго упорядочены по уникальному идентификатору, который состоит из двух чисел, разделенных дефисом, состоящим из отметки времени и порядкового номера, например 784738748-1, 784738748-2, 784738754-1 и пр.

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

  • каждое сообщение доставляется разным потребителям, поэтому невозможно, чтобы одно и то же сообщение было доставлено нескольким потребителям;
  • потребители идентифицируются внутри группы потребителей по имени, которое представляет собой строку с учетом регистра, которую должны выбрать клиенты, реализующие потребителей. Поэтому даже после отключения группа потребителей потока сохраняет все состояние, поскольку клиент снова будет утверждать, что является тем же потребителем. Однако, клиент должен предоставить уникальный идентификатор.
  • В каждой группе потребителей используется концепция первого идентификатора, который никогда не используется. Поэтому, когда потребитель запрашивает новые сообщения, он может предоставлять только те сообщения, которые ранее не доставлялись.
  • Для получения сообщения требуется явное подтверждение с использованием определенной команды. Redis интерпретирует подтверждение следующим образом: это сообщение было правильно обработано, поэтому его можно исключить из группы потребителей.
  • Группа потребителей отслеживает все сообщения, ожидающие в данный момент, то есть сообщения, которые были доставлены какому-либо потребителю из группы потребителей, но еще не подтверждены как обработанные. Благодаря этой функции при доступе к истории сообщений потока каждый потребитель увидит только те сообщения, которые были ему доставлены.

Таким образом, в Redis Streams группу потребителей можно представить как некоторое количество состояний потока. Чем Redis Streams отличается от Apache Kafka, рассмотрим далее.

Отличия Redis Streams от Apache Kafka

Redis Streams в некоторых отношениях похож на Kafka: команда XREAD действует как отдельные потребители Kafka, а XREADGROUP действует как группы потребителей Kafka. Однако, топики Kafka имеют разделы, которые позволяют распределять нагрузку между потребителями в группе, а в Redis Streams разделы отсутствуют. Kafka использует разделы топиков для высокого параллелизма и пропускной способности, поддерживая несколько потребителей, разделяющих нагрузку по обработке сообщений, а также многопоточность/несколько узлов на стороне сервера. Разделы также дают Kafka возможность обрабатывать события по порядку внутри каждого раздела. Redis Streams не может дать такой гарантии, позволяя лишь использовать несколько потоков с одним потребителем для каждого. В Kafka улучшено автоматическое управление группами потребителей, включая автоматическую перебалансировку потребителей, о которой мы писали здесь. И команда XREADGROUPS в Redis Streams, и Kafka поддерживают семантику доставки «хотя бы один раз» и «точно один раз» с командой XACKS в Redis Streams и ручными фиксациями смещения в Kafka, а не с автоматической фиксацией по умолчанию.

Критерий

Redis Pub/Sub

Redis Streams

Apache Kafka

XREAD

XREADGROUPS

Структура данных

Канал

Поток

Поток

Топик

Тип данных значения

String

Array

Array

Двоичный из-за сериализации

Явный ключ

Нет

Нет

Нет

Да, но не обязательно

Должны ли сообщения помещаться в памяти

Да

Да

Да

Нет

Сохранение доставленных сообщений

Нет

Да

Да

Да

Доставка отключенным потребителям

Нет

Да

Да

Да

Срок поставки зависит от количества потребителей

Да

Нет

Нет

Нет

Задержка

менее 1 мс

Менее 10 мс

Менее 10 мс

Менее 100 мс

Гарантия доставки максимум один раз (at-most-once)

Да

Нет

Нет

Нет

Гарантия минимум один раз (at-least-once)

Нет

Да

Да

Да

Обработка сообщений строго один раз (Exactly-once)

Нет

Нет

Да (с XACK)

Да (с ручной фиксацией)

Потребители должны отслеживать последний увиденный идентификатор (используется в следующем poll-опросе)

Нет

Да

Нет

Нет

Группы потребителей для распределения нагрузки

Нет

Нет

Да (круговой перебор)

Да (круговой перебор или явное указание раздела)

Ребалансировка групп потребителей

Нет

Нет

Вручную

Автоматически

Разделы для параллельного выполнения на стороне сервера

Нет

Нет

Нет

Да

Сохранение сообщений

Нет

Необязательно

Необязательно

Да

Репликация и восстановление после сбоя

Да

Да

Да

Да

Шаблон подписки

Да

Нет

Нет

Да

Таким образом, резюмируем варианты использования рассмотренных технологий:

  • Redis Pub/Sub подойдет, когда нужна быстрая (менее миллисекунды) доставка сообщений в реальном времени подключенным потребителям. При этом не важно, если сообщения не доставлены отключенным потребителям.
  • Redis Streams – отличный выбор, когда нужно отправить сообщения потребителям быстро (менее 10 мс), но надежно.
  • Apache Kafka нужна, если требуется надежность, отказоустойчивость и высокая производительность при работе с огромными объемами данных с гарантиями постоянного хранения и воспроизведения сообщений, а также быстрое время доставки (10-100 мс) и высокомасштабируемая обработка с помощью разделения топиков и групп потребителей.

Освойте администрирование и эксплуатацию Apache Kafka для потоковой аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://redis.io/docs/interact/pubsub/
  2. https://redis.io/docs/data-types/streams/
  3. https://www.instaclustr.com/blog/redis-streams-vs-apache-kafka/
Поиск по сайту