Как потоки Kafka обрабатывают распределенные данные - PullRequest
1 голос
/ 08 мая 2019

Я пытался просмотреть различные учебные пособия, но не совсем ясно по двум аспектам потоков Кафки. Давайте возьмем пример подсчета слов, упомянутый в: https://docs.confluent.io/current/streams/quickstart.html

// Serializers/deserializers (serde) for String and Long types
final Serde<String> stringSerde = Serdes.String();
final Serde<Long> longSerde = Serdes.Long();

// Construct a `KStream` from the input topic "streams-plaintext-input", where message values
// represent lines of text (for the sake of this example, we ignore whatever may be stored
// in the message keys).
KStream<String, String> textLines = builder.stream("streams-plaintext-input", Consumed.with(stringSerde, stringSerde));

KTable<String, Long> wordCounts = textLines
// Split each text line, by whitespace, into words.  The text lines are the message
// values, i.e. we can ignore whatever data is in the message keys and thus invoke
// `flatMapValues` instead of the more generic `flatMap`.
.flatMapValues(value -> Arrays.asList(value.toLowerCase().split("\\W+")))
// We use `groupBy` to ensure the words are available as message keys
.groupBy((key, value) -> value)
// Count the occurrences of each word (message key).
.count();

// Convert the `KTable<String, Long>` into a `KStream<String, Long>` and write to the output topic.
wordCounts.toStream().to("streams-wordcount-output", 
Produced.with(stringSerde, longSerde));

Пара вопросов здесь:
1.) Поскольку в исходном потоке нет ключей, два слова могут попасть в два разных узла, так как они могут попадать в разные разделы, и, следовательно, истинное количество будет объединением обоих. Это, кажется, не сделано здесь? Разные узлы, обслуживающие разделение одной и той же темы, координируют здесь подсчет?
2.) Когда новый поток генерируется каждой операцией (например, flatMapValues, groupBy и т. Д.), Перерасчитываются ли разделы для сообщений в этих подпотоках, чтобы они попадали на разные узлы?

Буду признателен за любую помощь здесь!

1 Ответ

1 голос
/ 09 мая 2019

1.) Поскольку в исходном потоке нет ключей, два слова могут попасть в два разных узла, так как они могут попадать в разные разделы, и, следовательно, истинный счет будет суммировать оба из них.Это, кажется, не сделано здесь?

Это сделано здесь.Это соответствующий код:

// We use `groupBy` to ensure the words are available as message keys
.groupBy((key, value) -> value)

Здесь «слова» становятся новым ключом сообщения, что означает, что слова перераспределяются так, что каждое слово помещается только в один раздел.

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

Нет, нет.Раздел обрабатывается только одним узлом (точнее: только одной потоковой задачей, см. Ниже).

2.) Поскольку новый поток создается каждой операцией (например, flatMapValues, groupBy и т. Д.)перераспределяются ли разделы для сообщений в этих подпотоках, чтобы они попадали на разные узлы?

Не уверен, что я понимаю ваш вопрос, в частности комментарий "пересчитан".Операции (например, агрегации) всегда выполняются для каждого раздела, и Kafka Streams отображает разделы в потоковые задачи (слегка упрощено: раздел всегда обрабатывается одной и только одной потоковой задачей).Потоковые задачи выполняются различными экземплярами вашего приложения Kafka Streams, которое обычно выполняется на разных контейнерах / виртуальных машинах / машинах.В случае необходимости данные необходимо будет повторно разделить (см. Вопрос № 1 и ответ выше), чтобы операция могла привести к ожидаемому результату - возможно, именно это вы имеете в виду, когда говорите «пересчитано».

Я бы посоветовал прочитать документацию Кафки, такую ​​как https://kafka.apache.org/documentation/streams/architecture#streams_architecture_tasks.

...