Поговорим о дизайне очереди.

У нас есть очень длинная книга, которую мы хотим, чтобы ее прочитали многие. Кто-то может читать во время обеденного перерыва, кто-то читает по понедельникам, а кто-то забирает это домой на выходные. Книга настолько длинная, что в любой момент ее читают сотни людей.

Читатели нашей книги должны следить за тем, где они находятся в нашей книге, поэтому они отслеживают свое местоположение, помещая закладку в книгу. Некоторые читатели читают очень медленно, оставляя закладки ближе к началу. Другие читатели сдаются на полпути, оставляя свое на полпути и никогда не возвращаясь к нему.

Что еще хуже, мы добавляем страницы в эту книгу каждый день. На самом деле никто не может закончить эту книгу.

В конце концов наша книга заполняется закладками, пока, наконец, однажды она не станет слишком тяжелой для переноски, и никто больше не сможет ее прочитать.

Затем один очень умный человек решил, что читателям нельзя разрешать размещать закладки внутри книги, а вместо этого они должны записывать страницу, которую они открывают в своем дневнике.

Это дизайн Apache Kafka, и это очень устойчивый дизайн. Читатели часто не являются ответственными гражданами и часто не убирают за собой, а книга может быть журналом всех важных событий, которые происходят в нашей компании.

Обычный альтернативный дизайн для других очередей заключается в том, что служба очередей отслеживает, где находятся считыватели, - это означает необходимость выделения памяти для каждого считывателя. Читатели с плохим поведением могут неоднократно запрашивать новые сеансы очереди, и это может привести к перегрузке службы очереди. Часто это не лучший дизайн, так как мы хотим, чтобы читатели могли свободно читать, не рискуя стоять в очереди.

Apache Kafka

Kafka спроектирован вокруг потока событий, таких как:

1001. «tim» приобрел туристическую сделку «fiji»
1002. «tim» имеет обновил свои настройки подписки на "daily"
1003. "sam" зарегистрирован in с использованием "iphone"
1004. "sam" открыл предложение о путешествии "bali '
1005.' sam 'вошел в с помощью' настольного Интернета '
1006. "sam" приобрел сделку "bali".

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

Kafka отлично звучит, почему Redis Streams?

Kafka - отличный выбор для хранения потока событий, и он рассчитан на большие масштабы. Kafka берет на себя дополнительную сложность, чтобы достичь такого масштаба. Для подготовки и управления настройкой Kafka необходимо понимание некоторых сложных концепций. Для небольших проектов более простая и компактная система может быть лучшим выбором. Хотя всем нам нравится решать проблемы масштаба Google, это очень редко требуется.

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

Чтобы начать работу с Redis Streams, я представлю две новые команды, которые есть в версии 5 Redis. Чтобы следовать этому примеру, вы можете создать онлайн-экземпляр Redis для использования AWS ElastiCache примерно за 2 минуты.

Запись в поток Redis

XADD имя_потока * ключ1 значение1 ключ2 значение2 (и т. Д.)

XADD позволяет нам писать поток событий. Давайте создадим поток событий, отражающий приведенный выше пример. Назовем наш поток «событиями».

XADD events * user tim action purchase item travel:fiji
XADD events * user tim action preferences subscription daily
XADD events * user sam action login platform iPhone
XADD events * user sam action visit item travel:bali
XADD events * user sam action login platform “desktop web”
XADD events * user sam action purchase item travel:bali

Знак «*» используется для отделения необязательных параметров от набора ключевых значений.

Это запишет все эти действия в пар «событий».

Чтение из потока Redis

XREAD COUNT 2 STREAMS события ID элемента

XREAD позволяет нам читать элементы из этой очереди. Давайте читать по два элемента за раз:

demo.wiftycloud.com:6379> XREAD COUNT 2 STREAMS events 0
1) 1) “events”
   2) 1) 1) 1512991598699–0
         2) 1) “user”
            2) “tim”
            3) “action”
            4) “purchase”
            5) “item”
            6) “travel:fiji”
      2) 1) 1512991602438–0
         2) 1) “user”
            2) “tim”
            3) “action”
            4) “preferences”
            5) “subscription”
            6) “daily”

Мы запрашиваем элементы в потоке «события», начиная с начала списка (передавая «0»). Мы запросили только 2 элемента. Чтобы получить следующие два элемента, вместо того, чтобы начинать с «0», теперь мы начинаем с последнего идентификатора, возвращенного Redis, который в приведенном выше примере равен «1512991602438–0».

> XREAD COUNT 2 streams events 1512991602438–0
1) 1) “events”
   2) 1) 1) 1512991605766-0
         2) 1) “user”
            2) “sam”
            3) “action”
            4) “logon”
            5) “platform”
            6) “iPhone”
      2) 1) 1512991617871-0
         2) 1) “user”
            2) “sam”
            3) “action”
            4) “visit”
            5) “item”
            6) “travel:bali”

Доступны и другие варианты - BLOCK позволяет нам заставить сервер Redis ждать соединения, пока не станут доступны события.

Между этими двумя командами, XADD и XREAD, мы можем очень легко построить очередь бизнес-событий.

Пример Node.js

Библиотека поддержки Streams еще не совсем готова, однако в настоящее время можно использовать пользовательские команды. Пример использования ioredis можно найти здесь.

TL;DR

Kafka потрясающий, и Redis Streams становится отличной альтернативой LoFi для Kafka для управления потоками событий.