Поговорим о дизайне очереди.
У нас есть очень длинная книга, которую мы хотим, чтобы ее прочитали многие. Кто-то может читать во время обеденного перерыва, кто-то читает по понедельникам, а кто-то забирает это домой на выходные. Книга настолько длинная, что в любой момент ее читают сотни людей.
Читатели нашей книги должны следить за тем, где они находятся в нашей книге, поэтому они отслеживают свое местоположение, помещая закладку в книгу. Некоторые читатели читают очень медленно, оставляя закладки ближе к началу. Другие читатели сдаются на полпути, оставляя свое на полпути и никогда не возвращаясь к нему.
Что еще хуже, мы добавляем страницы в эту книгу каждый день. На самом деле никто не может закончить эту книгу.
В конце концов наша книга заполняется закладками, пока, наконец, однажды она не станет слишком тяжелой для переноски, и никто больше не сможет ее прочитать.
Затем один очень умный человек решил, что читателям нельзя разрешать размещать закладки внутри книги, а вместо этого они должны записывать страницу, которую они открывают в своем дневнике.
Это дизайн 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 для управления потоками событий.