Spark结构化流不从先前的偏移量重新启动

时间:2018-08-20 16:35:08

标签: apache-spark apache-spark-sql spark-streaming

我有一个流媒体Spark应用程序,它可以从kafka流中读取消息,如下所示;

    m_kafkaEvents = m_sparkSession.readStream().format("kafka")
        .option("kafka.bootstrap.servers", strKafkaAddress)
        .option("subscribe", InsightConstants.IP_INSIGHT_EVENT_TOPIC)
        .option("maxOffsetsPerTrigger", "100000")
        .option("startingOffsets", "latest")
        .option("failOnDataLoss", false)
        .load()
        .select(
            functions.col("key").cast("string").as(InsightConstants.IP_SYS_INSTANCE_ID), 
            functions.col("value").cast("string").as("event"),
            functions.col("partition"),
            functions.col("offset"))
        .as(ExpressionEncoder.javaBean(InputEvent.class));

然后我处理消息并按如下所示将其写入Kakfa输出接收器;

 DataStreamWriter<SessionUpdate> eventsStream = sessionUpdates
        .writeStream()
        .queryName(strQueryName)
        .outputMode("append")        .trigger(Trigger.ProcessingTime(m_insightDeployment.getIdentifierProcessor().getTriggerInterval()))
        .option("checkpointLocation", strCheckpointLocation)
        .foreach(foreachWriter);

在ForeachWriter中,

我将消息推送到kafka主题中,如下所示;

    try
    {
      String strKafkaAddress = m_strKafkaHost + ":" + m_iKafkaPort.toString();
      Properties oProperties = new Properties();
      oProperties.put("bootstrap.servers", strKafkaAddress);
      oProperties.put("acks",              "all");
      oProperties.put("retries",           3);
      oProperties.put("batch.size",        16384);
      oProperties.put("linger.ms",         1);
      oProperties.put("buffer.memory",     33554432);
      oProperties.put("key.serializer",    "org.apache.kafka.common.serialization.StringSerializer");
      oProperties.put("value.serializer",  "org.apache.kafka.common.serialization.StringSerializer");

      m_oProducer = new org.apache.kafka.clients.producer.KafkaProducer<String, String>(oProperties);
    }
    catch (Throwable oThrowable)
    {
      oThrowable.printStackTrace();
    }
  }

    ProducerRecord<String, String> oMessage =
        new ProducerRecord<String, String>(in_strTopic, in_strKey, in_strPayload);

      m_oProducer.send(oMessage);

使用以下代码在spark app重新启动时(我通过控制台手动将其杀死,并且一段时间后spark app由驱动程序自行重启),它将再次从开始读取消息,而不是先前的消息基于检查点的偏移量。 我看到检查点位置已创建,并且好像spark应用程序未从该检查点位置读取。因此,我看到重复的消息。

这里似乎缺少了一些东西。有人可以推荐这里缺少的部分吗?

提前感谢您的帮助。

0 个答案:

没有答案