Одна из первых вещей, о которых я думаю, когда использую новый сервис (например, хранилище данных без RDBMS или очередь сообщений), это: «Как мне структурировать мои данные?».
Я читал и смотрел некоторые вводные материалы. В частности, возьмем, например, Kafka: распределенную систему обмена сообщениями для обработки журналов , которая пишет:
- «Тема - это контейнер, с которым связаны сообщения»
- «Наименьшей единицей параллелизма является раздел темы. Это означает, что все сообщения, принадлежащие определенному разделу темы, будут потребляться потребителем в группе потребителей».
Зная это, что будет хорошим примером, который иллюстрирует, как использовать темы и разделы? Когда что-то должно быть темой? Когда что-то должно быть разделом?
В качестве примера, скажем, мои (Clojure) данные выглядят так:
{:user-id 101 :viewed "/page1.html" :at #inst "2013-04-12T23:20:50.22Z"}
{:user-id 102 :viewed "/page2.html" :at #inst "2013-04-12T23:20:55.50Z"}
Должна ли тема быть основана на user-id
? viewed
?at
? А как насчет раздела?
Как мне решить?
apache-kafka
Дэвид Дж.
источник
источник
Ответы:
При структурировании ваших данных для Kafka это действительно зависит от того, как они должны быть использованы.
На мой взгляд, тема - это группа сообщений аналогичного типа, которые будут потребляться одним и тем же типом потребителя, поэтому в приведенном выше примере у меня будет просто одна тема, и если вы решите использовать какой-то другой вид Данные через Kafka, вы можете добавить новую тему для этого позже.
Темы зарегистрированы в ZooKeeper, что означает, что вы можете столкнуться с проблемами, если попытаетесь добавить слишком много из них, например, в случае, если у вас миллион пользователей и вы решили создать тему для каждого пользователя.
Разделы, с другой стороны, - это способ распараллеливания потребления сообщений, и общее количество разделов в кластере брокера должно быть, по крайней мере, таким же, как количество потребителей в группе потребителей, чтобы иметь смысл функции разделения. Потребители в группе потребителей будут разделять бремя обработки темы между собой в соответствии с разделением, так что один потребитель будет касаться только сообщений в самом разделе, которому он «назначен».
Разделение может быть явно задано с использованием ключа разделения на стороне производителя, или, если оно не предусмотрено, для каждого сообщения будет выбран случайный раздел.
источник
Kafka is designed to have of the order of few thousands of partitions roughly less than 10,000. And the main bottleneck is zookeeper. A better way to design such a system is to have fewer partitions and use keyed messages to distribute the data over a fixed set of partitions.
Заставляет меня думать, что это не тот инструмент для того, что вы описали - но более того, тема будет «События просмотра страницы»? И все просмотры страниц будут в этой «теме». Кажется, разделы больше о параллелизме, репликах и прочем?Как только вы узнаете, как разделить ваш поток событий, название темы будет простым, поэтому давайте сначала ответим на этот вопрос.
@Ludd верен - выбранная вами структура раздела будет зависеть в значительной степени от того, как вы хотите обработать поток событий. В идеале вам нужен ключ раздела, который означает, что ваша обработка событий локальна для раздела .
Например:
:user-id
. Таким образом, все события, связанные с активностью сайта одного пользователя, будут доступны в одном разделе. Это означает, что механизм потоковой обработки, такой как Apache Samza, может рассчитывать среднее время пребывания на месте для данного пользователя, просто просматривая события в одном разделе. Это избавляет от необходимости выполнять какие-либо дорогостоящие глобальные разделы обработки:viewed
страницу. Опять же, Samza сможет вести подсчет просмотров данной страницы, просто просматривая события в одном разделе.Как правило, мы пытаемся избежать необходимости полагаться на глобальное состояние (например, вести учет в удаленной базе данных, такой как DynamoDB или Cassandra), и вместо этого иметь возможность работать с использованием локального состояния раздела. Это потому, что локальное состояние является фундаментальным примитивом в обработке потока .
Если вам нужны оба вышеупомянутых варианта использования, то общая схема с Kafka - сначала разделить, скажем
:user-id
, а затем повторно разделить ,:viewed
готовясь к следующему этапу обработки.По названиям тем - очевидный здесь будет
events
илиuser-events
. Чтобы быть более конкретным, вы можете пойти сevents-by-user-id
и / илиevents-by-viewed
.источник
Это не совсем связано с вопросом, но если вы уже определились с логическим разделением записей по темам и хотите оптимизировать количество тем / разделов в Kafka, этот блог может пригодиться.
Ключевые выводы в двух словах:
В общем, чем больше разделов в кластере Kafka, тем выше пропускная способность. Пусть максимальный предел, достижимый на одном разделе для производства, будет p, а потребление - c . Допустим, ваша целевая пропускная способность равна т . Тогда вам нужно иметь как минимум max ( t / p , t / c ) разделов.
В настоящее время в Kafka каждый брокер открывает дескриптор файла как индекса, так и файла данных каждого сегмента журнала. Таким образом, чем больше разделов, тем выше нужно настроить ограничение дескриптора открытого файла в базовой операционной системе. Например, в нашей производственной системе мы однажды увидели ошибку
too many files are open
, в которой было около 3600 тематических разделов.Когда брокер нечисто выключается (например, kill -9), наблюдаемая недоступность может быть пропорциональна количеству разделов.
Сквозная задержка в Kafka определяется временем от момента публикации сообщения производителем до момента, когда сообщение прочитано потребителем. Как правило, если вы заботитесь о задержке, возможно, хорошей идеей будет ограничить число разделов на брокер до 100 x b x r , где b - количество брокеров в кластере Kafka, а r - коэффициент репликации.
источник
Я думаю, что название темы - это своего рода сообщение, и производитель публикует сообщение в теме, а потребитель подписывает сообщение через тему подписки.
В теме может быть много разделов. раздел хорош для параллелизма. раздел также является единицей репликации, поэтому в Кафке лидер и последователь также упоминаются на уровне раздела. На самом деле раздел - это упорядоченная очередь, в которой заказ является доставленным сообщением. И тема состоит из одной или нескольких очередей в простом слове. Это полезно для моделирования нашей структуры.
Кафка разработана LinkedIn для агрегации и доставки журналов. эта сцена очень хороша в качестве примера.
События пользователя в вашей сети или приложении могут регистрироваться вашим веб-сервером, а затем отправляться брокеру Kafka через производителя. В продюсере вы можете указать метод разделения, например: тип события (другое событие сохраняется в другом разделе) или время события (разделить день на другой период в соответствии с логикой вашего приложения) или тип пользователя или просто нет логики и сбалансировать все журналы на много разделов.
Что касается рассматриваемого вами случая, вы можете создать одну тему, называемую «page-view-event», и создать N разделов с помощью хеш-ключей для равномерного распределения журналов по всем разделам. Или вы можете выбрать логику раздела, чтобы распределять журналы по своему духу.
источник