Spark streaming с Kafka - createDirectStream vs createStream

Мы использовали искрообразование с кафкой какое-то время, и до сих пор мы использовали метод createStream от KafkaUtils.

Мы только начали изучать createDirectStream и, как это было по двум причинам:

1) Лучше/проще "точно один раз" семантика

2) Лучшая корреляция раздела раздела kafka с разделами rdd

Я заметил, что createDirectStream отмечен как экспериментальный. Вопрос у меня есть (извините, если это не очень специфично):

Должен ли мы изучить метод createDirectStream, если один раз для нас очень важен? Будет здорово, если вы, ребята, сможете поделиться своим опытом с этим. Имеем ли мы риск столкнуться с другими проблемами, такими как надежность и т.д.

Ответ 1

Создатель прямого подхода (Коди) здесь предлагает отличный обширный блог.

В общем, читая раздел о семантике доставки Kafka, последняя часть гласит:

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

Это в основном означает "мы даем вам хотя бы один раз из коробки, если вы хотите ровно один раз, что на вас". Кроме того, в сообщении блога говорится о гарантии семантики "точно один раз", которую вы получаете от Spark с обоими подходами (прямой и на основе получателя, выделено мое):

Во-вторых, понять, что Spark не гарантирует ровно один раз семантика для действий вывода. Когда потоковое руководство Spark говорит примерно один раз, это относится только к данному элементу в СДР включается в расчетное значение один раз, в чисто функциональный смысл. Любые побочные операции вывода (то есть все, что вы делаете в foreachRDD, чтобы сохранить результат) может быть повторен, потому что любой этап процесс может завершиться неудачей и будет повторен.

Кроме того, в документации Spark говорится об обработке на основе получателя:

Первый подход (на основе Receiver) использует высокоуровневый API Kafkas для хранения потребляемых смещения в Zookeeper. Это традиционно способ потребления данных из Кафки. Пока этот подход (в сочетании с записью в журнал впереди) может обеспечить нулевую потерю данных (т.е. хотя бы один раз семантики), есть Небольшая вероятность того, что некоторые записи могут быть использованы дважды при некоторых сбоях.

По сути, это означает, что если вы используете поток на основе Receiver со Spark, у вас все еще могут быть дублированные данные на случай неудачного преобразования выходных данных, хотя бы один раз.

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

Я рекомендую прочитать сообщение в блоге (ссылка выше) и семантику доставки на странице документации Kafka. В заключение я определенно рекомендую вам обратиться к прямому потоковому подходу.