Как сохранить последнее смещение, которое Spark потребляет ZK или Kafka и может прочитать после перезапуска

Я использую Kafka 0.8.2 для получения данных из AdExchange, затем я использую Spark Streaming 1.4.1 для хранения данных до MongoDB.

Моя проблема в том, что я перезапускаю свой Spark Streaming Job, например, обновляю новую версию, исправляю ошибку, добавляю новые функции. Он будет продолжать читать последние offset of kafka в то время, после чего я потеряю данные. AdX нажимаем на kafka во время перезапуска задания.

Я пробую что-то вроде auto.offset.reset -> smallest, но оно будет получать от 0 до > последнего, тогда данные были огромны и дублировались в db.

Я также пытаюсь установить конкретные group.id и consumer.id в Spark, но это то же самое.

Как сохранить последнюю искру offset, потребляемую до zookeeper или kafka, затем можно прочитать от этого до последнего offset?

Ответ 1

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

Просто посмотрите на api здесь: http://spark.apache.org/docs/latest/api/java/org/apache/spark/streaming/kafka/KafkaUtils.html Карта, о которой я говорил, обычно называется: fromOffsets

Вы можете вставить данные на карту:

startOffsetsMap.put(TopicAndPartition(topicName,partitionId), startOffset)

И используйте его при создании прямого потока:

KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder, (String, String)](
                streamingContext, kafkaParams, startOffsetsMap, messageHandler(_))

После каждой итерации вы можете получить обработанные смещения, используя:

rdd.asInstanceOf[HasOffsetRanges].offsetRanges

Вы могли бы использовать эти данные для построения карты fromOffsets в следующей итерации.

Вы можете увидеть полный код и использовать здесь: https://spark.apache.org/docs/latest/streaming-kafka-integration.html в конце страницы

Ответ 2

Здесь некоторый код, который вы можете использовать для хранения смещений в ZK http://geeks.aretotally.in/spark-streaming-kafka-direct-api-store-offsets-in-zk/

И здесь некоторый код, который вы можете использовать для использования смещения при вызове KafkaUtils.createDirectStream: http://geeks.aretotally.in/spark-streaming-direct-api-reusing-offset-from-zookeeper/

Ответ 3

Чтобы добавить к Майклу Копаниуву ответ, если вы действительно хотите использовать ZK в качестве места, где вы храните и загружаете карту смещений, вы можете.

Однако, поскольку ваши результаты не выводятся на ZK, вы не получите надежную семантику, если ваша выходная операция не является идемпотентной (что кажется, что это не так).

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

Подробнее см. https://www.youtube.com/watch?v=fXnNEq1v3VA

Ответ 4

Я еще не понял это на 100%, но лучше всего настроить JavaStreamingContext.checkpoint().

См. https://spark.apache.org/docs/1.3.0/streaming-programming-guide.html#checkpointing для примера.

По некоторым сообщениям в блоге https://github.com/koeninger/kafka-exactly-once/blob/master/blogpost.md есть некоторые оговорки, но похоже, что это связано с определенными случайными случаями, на которые ссылаются только и фактически не объяснено.