重新启动后从检查点目录重新加载状态时,Spark Broadcast变量导致失败

时间:2018-12-07 11:54:20

标签: apache-spark

我有一个Spark Streaming应用程序(使用spark 1.6.1),可从Kafka读取数据。我正在hdfs上使用spark checkpoint目录从故障中恢复。

代码在每个批次的开始使用广播变量和映射,如下所示

public static void execute(JavaPairDStream<String, MyEvent> events) {
  final Broadcast<Map<String, String>> appConfig =  MyStreamConsumer.ApplicationConfig.getInstance(new    JavaSparkContext(events.context().sparkContext()));

在运行时提交作业时,一切正常,并且来自kafka的所有事件均已正确处理。从故障中恢复时会出现问题(通过重新启动计算机spark进行测试)-spark stream应用程序实际上正确启动,并且在运行作业的情况下UI看起来一切正常,但是通过以下异常发送数据后,调用此方法时遇到此问题(并且作业崩溃):

appConfig.value() (the broadcast variable from the start!)

由于Spark作业错误而失败

  Caused by: java.lang.ClassCastException: org.apache.spark.util.SerializableConfiguration cannot be cast to java.util.Map

如果我在spark用户界面中杀死了驱动程序,然后从命令行重新提交了作业,那么一切都会恢复正常。 但是对我们产品的要求是,它可以自动从故障中恢复,甚至可以重新启动任何群集节点,因此我必须修复以上问题。 问题肯定与重新启动后使用Broadcast变量以及从spark checkpoint目录加载状态有关

另外请注意,我确实正确创建了广播实例(延迟/单个):

public static Broadcast<Map<String, String>> getInstance(JavaSparkContext sparkContext) {
    if (instance == null) {

我确实意识到这个问题似乎与以下方面有关: Is it possible to recover an broadcast value from Spark-streaming checkpoint

但是我无法按照说明进行修复

1 个答案:

答案 0 :(得分:0)

回答我自己的问题,其他人可能会发现它很有用: 奇怪,但是如果我将以下代码移至execute方法的开头,以下内容似乎已解决了该问题:appConfig.value()并将其分配给那里的普通映射变量。

然后,如果我只是在匿名FlatMapFunction代码中使用此映射变量,而不是在appConfig.value()中使用-即使重新启动后,一切都可以正常工作。

再次,不确定为什么会这样,但是确实如此...