我有一个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
但是我无法按照说明进行修复
答案 0 :(得分:0)
回答我自己的问题,其他人可能会发现它很有用: 奇怪,但是如果我将以下代码移至execute方法的开头,以下内容似乎已解决了该问题:appConfig.value()并将其分配给那里的普通映射变量。
然后,如果我只是在匿名FlatMapFunction代码中使用此映射变量,而不是在appConfig.value()中使用-即使重新启动后,一切都可以正常工作。
再次,不确定为什么会这样,但是确实如此...