我是新来的火花,有些事情对我来说还不清楚。但是基础知识表明,只有累加器是可变变量,可以在执行程序之间进行更新,并且驱动程序可以检索其值。代码中初始化的任何其他变量(在执行程序之间进行更新)由于它们是独立的JVM,因此更新后的值不会中继回驱动程序。
我正在做一个项目的一部分,该项目将Zookeeper的偏移量存储在数据结构中以备将来使用。由于偏移量是在执行程序上获得的,因此几乎不可能有一个共享的数据结构来将每个分区的偏移量也更新回驱动程序。直到我在https://spark.apache.org/docs/2.3.0/streaming-kafka-0-8-integration.html中遇到此代码为止。
AtomicReference<OffsetRange[]> offsetRanges = new AtomicReference<>();
directKafkaStream.transformToPair(rdd -> {
OffsetRange[] offsets = ((HasOffsetRanges) rdd.rdd()).offsetRanges();
offsetRanges.set(offsets); return rdd;
}).map(
...
).foreachRDD(rdd -> { for (OffsetRange o : offsetRanges.get()) {
System.out.println(
o.topic() + " " + o.partition() + " " + o.fromOffset() + " " + o.untilOffset()
);}
...
});
System.out.println(Arrays.toString(offsetRanges.get()));
这与基本理论相矛盾,因为当我在驱动程序中访问AtomicReference<OffsetRange[]> offsetRanges
的值时,即使它应该返回,我也会获得正确的更新值(在执行程序代码中的transformToPair
方法中更新)。我的回应为空或空。请有人可以向我解释这种行为吗?
答案 0 :(得分:3)
是否可以在不使用累加器的情况下创建可变的共享数据结构?
否。
当我访问
的值时,这与基本理论矛盾
没有,因为未在驱动程序外部修改该值。 transformToPair
的关闭是在驱动程序而不是执行程序上执行的。
因此offsetRanges.set(offsets)
是在原始offsetRanges
值所在的同一JVM上执行的。