Apache spark 在spark中不使用累加器就可以创建可变的共享数据结构吗?

Apache spark 在spark中不使用累加器就可以创建可变的共享数据结构吗?,apache-spark,spark-streaming,Apache Spark,Spark Streaming,我对spark是个新手,有些事情我还不太清楚。但基本知识表明,只有累加器是可变变量,可以跨执行器更新,其值可以由驱动程序检索。在代码中初始化的任何其他变量,这些变量在执行器之间更新。更新的值不会中继回驱动程序,因为它们是单独的JVM 我正在一个项目中工作,该项目将zookeeper的偏移量存储在一个数据结构中,以备将来使用。由于偏移量是在执行器上获得的,所以几乎不可能有一个共享的数据结构,它也会将每个分区的偏移量更新回驱动程序 AtomicReference offsetRanges=新的Ato

我对spark是个新手,有些事情我还不太清楚。但基本知识表明,只有累加器是可变变量,可以跨执行器更新,其值可以由驱动程序检索。在代码中初始化的任何其他变量,这些变量在执行器之间更新。更新的值不会中继回驱动程序,因为它们是单独的JVM

我正在一个项目中工作,该项目将zookeeper的偏移量存储在一个数据结构中,以备将来使用。由于偏移量是在执行器上获得的,所以几乎不可能有一个共享的数据结构,它也会将每个分区的偏移量更新回驱动程序

AtomicReference offsetRanges=新的AtomicReference();
directKafkaStream.transformToPair(rdd->{
OffsetRange[]偏移=((HasOffsetRanges)rdd.rdd()).offsetRanges();
设置(偏移量);返回rdd;
}).地图(
...
).foreachRDD(rdd->{for(OffsetRange o:offsetRanges.get()){
System.out.println(
o、 topic()+“”+o.partition()+“”+o.fromOffset()+“”+o.UntiloOffset()
);}    
...
});
System.out.println(Arrays.toString(offsetRanges.get());
这与基本理论相矛盾,因为当我访问驱动程序中的
AtomicReference offsetRanges
值时,我得到了正确的更新值(在执行器代码中的
transformToPair
方法中更新),即使它应该返回null或空响应。有人能给我解释一下这种行为吗

在spark中不使用累加器就可以创建可变的共享数据结构吗

没有

这与基本理论相矛盾,因为当我访问

它不会,因为该值未在驱动程序外部修改。
transformToPair
的关闭在驱动程序上执行,而不是在执行器上执行

因此,
offsetRanges.set(offsets)
在原始
offsetRanges
值所在的同一JVM上执行

在spark中不使用累加器就可以创建可变的共享数据结构吗

没有

这与基本理论相矛盾,因为当我访问

它不会,因为该值未在驱动程序外部修改。
transformToPair
的关闭在驱动程序上执行,而不是在执行器上执行


因此,
offsetRanges.set(offsets)
在原始
offsetRanges
值所在的同一JVM上执行。

这就解释了这一点。我认为所有的关闭都是由执行人执行的。有没有一条经验法则可以让我们知道某个特定的函数是在驱动程序还是执行程序上执行的?@RonakHingar你真的应该单独问这个问题。任何处理RDD的操作都只能在驱动程序上执行。您使用的任何RDD方法通常(但不总是)在执行器上执行。很简单,不是吗?:)@这是迄今为止我遇到的最简洁的解释。谢谢这就解释了。我认为所有的关闭都是由执行人执行的。有没有一条经验法则可以让我们知道某个特定的函数是在驱动程序还是执行程序上执行的?@RonakHingar你真的应该单独问这个问题。任何处理RDD的操作都只能在驱动程序上执行。您使用的任何RDD方法通常(但不总是)在执行器上执行。很简单,不是吗?:)@这是迄今为止我遇到的最简洁的解释。谢谢
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()));