Моделирование данных с Kafka? Темы и разделы

168

Одна из первых вещей, о которых я думаю, когда использую новый сервис (например, хранилище данных без 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? А как насчет раздела?

Как мне решить?

Дэвид Дж.
источник
3
Странно, это говорит о темах и разделах, но не обязательно об эволюции данных внутри них. Что, если вы хотите присоединить пользовательские агенты или заголовки к этим событиям «пользовательского просмотра»? Как вы развиваете и доносите это до конечных потребителей?
OneCricketeer

Ответы:

136

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

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

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

Разделы, с другой стороны, - это способ распараллеливания потребления сообщений, и общее количество разделов в кластере брокера должно быть, по крайней мере, таким же, как количество потребителей в группе потребителей, чтобы иметь смысл функции разделения. Потребители в группе потребителей будут разделять бремя обработки темы между собой в соответствии с разделением, так что один потребитель будет касаться только сообщений в самом разделе, которому он «назначен».

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

Ландал
источник
5
Таким образом, вместо того, чтобы использовать темы в качестве способа получения данных по идентификатору пользователя, тем самым подавляя Zookeeper, лучше разделить по идентификатору пользователя, а потребители на основе идентификатора пользователя подписываются на каждый раздел, если?
Равиндранат Акила
4
@RavindranathAkila 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. Заставляет меня думать, что это не тот инструмент для того, что вы описали - но более того, тема будет «События просмотра страницы»? И все просмотры страниц будут в этой «теме». Кажется, разделы больше о параллелизме, репликах и прочем?
Дембински
Спасибо :) Наконец-то у меня есть ответ: P
Равиндранат Акила
62

Как только вы узнаете, как разделить ваш поток событий, название темы будет простым, поэтому давайте сначала ответим на этот вопрос.

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

Например:

  1. Если вам небезразлично среднее время пребывания пользователей на сайте, то вам следует разделить на :user-id. Таким образом, все события, связанные с активностью сайта одного пользователя, будут доступны в одном разделе. Это означает, что механизм потоковой обработки, такой как Apache Samza, может рассчитывать среднее время пребывания на месте для данного пользователя, просто просматривая события в одном разделе. Это избавляет от необходимости выполнять какие-либо дорогостоящие глобальные разделы обработки
  2. Если вы заботитесь о самых популярных страницах на вашем сайте, вам следует разделить :viewedстраницу. Опять же, Samza сможет вести подсчет просмотров данной страницы, просто просматривая события в одном разделе.

Как правило, мы пытаемся избежать необходимости полагаться на глобальное состояние (например, вести учет в удаленной базе данных, такой как DynamoDB или Cassandra), и вместо этого иметь возможность работать с использованием локального состояния раздела. Это потому, что локальное состояние является фундаментальным примитивом в обработке потока .

Если вам нужны оба вышеупомянутых варианта использования, то общая схема с Kafka - сначала разделить, скажем :user-id, а затем повторно разделить , :viewedготовясь к следующему этапу обработки.

По названиям тем - очевидный здесь будет eventsили user-events. Чтобы быть более конкретным, вы можете пойти с events-by-user-idи / или events-by-viewed.

Алекс Дин
источник
8
Я видел ссылки, в которых вы бы опубликовали события по двум темам: по одной на одного работника / предполагаемое использование. В этом случае может быть две темы с двумя разными схемами разбиения.
Франсуа Босолей
7

Это не совсем связано с вопросом, но если вы уже определились с логическим разделением записей по темам и хотите оптимизировать количество тем / разделов в 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 - коэффициент репликации.

Bitswazsky
источник
4

Я думаю, что название темы - это своего рода сообщение, и производитель публикует сообщение в теме, а потребитель подписывает сообщение через тему подписки.

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

Кафка разработана LinkedIn для агрегации и доставки журналов. эта сцена очень хороша в качестве примера.

События пользователя в вашей сети или приложении могут регистрироваться вашим веб-сервером, а затем отправляться брокеру Kafka через производителя. В продюсере вы можете указать метод разделения, например: тип события (другое событие сохраняется в другом разделе) или время события (разделить день на другой период в соответствии с логикой вашего приложения) или тип пользователя или просто нет логики и сбалансировать все журналы на много разделов.

Что касается рассматриваемого вами случая, вы можете создать одну тему, называемую «page-view-event», и создать N разделов с помощью хеш-ключей для равномерного распределения журналов по всем разделам. Или вы можете выбрать логику раздела, чтобы распределять журналы по своему духу.

GuangshengZuo
источник