Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在RDD映射操作中更新全局变量_Scala_Apache Spark_Global Variables_Rdd - Fatal编程技术网

Scala 如何在RDD映射操作中更新全局变量

Scala 如何在RDD映射操作中更新全局变量,scala,apache-spark,global-variables,rdd,Scala,Apache Spark,Global Variables,Rdd,我有RDD[(Int,Array[Double]),然后,我调用了一个类函数 val rdd = spark.sparkContext.parallelize(Seq( (1, Array(2.0,5.0,6.3)), (5, Array(1.0,3.3,9.5)), (1, Array(5.0,4.2,3.1)), (2, Array(9.6,6.3,2.3)), (1, Array(8.5,2.5,1.2)),

我有RDD[(Int,Array[Double]),然后,我调用了一个类函数

val rdd = spark.sparkContext.parallelize(Seq(
        (1, Array(2.0,5.0,6.3)),
        (5, Array(1.0,3.3,9.5)),
        (1, Array(5.0,4.2,3.1)),
        (2, Array(9.6,6.3,2.3)),
        (1, Array(8.5,2.5,1.2)),
        (5, Array(6.0,2.4,7.8)),
        (2, Array(7.8,9.1,4.2))
      )
    )
 val new_class = new ABC
 new_class.demo(data)
在类中,声明了一个全局变量值=0。在demo()中声明了新变量new_value=0。映射操作完成后,新的_值将更新,并在映射内打印更新后的值

class ABC extends Serializable {
        var value  = 0
        def demo(data_new : RDD[(Int ,Array[Double])]): Unit ={
            var new_value = 0
            data_new.coalesce(1).map(x => {
                if(x._1 == 1)
                    new_value = new_value + 1
                println(new_value)
                value = new_value
            }).count()
            println("Outside-->" +value)
        }
    }
输出:-

1
1
2
2
3
3
3
Outside-->0

映射操作后如何更新全局变量值?

否您不能从映射内部更改全局变量

如果您试图计算函数中的一个数,则可以使用过滤器

val value = data_new.filter(x => (x._1 == 1)).count 
println("Outside-->" +value)
输出:

Outside-->3
此外,不建议使用可变变量
var
。您应该始终尝试使用不可变as
val


我希望这有帮助

不,您不能从地图内部更改全局变量

如果您试图计算函数中的一个数,则可以使用过滤器

val value = data_new.filter(x => (x._1 == 1)).count 
println("Outside-->" +value)
输出:

Outside-->3
此外,不建议使用可变变量
var
。您应该始终尝试使用不可变as
val


我希望这有帮助

我不确定您在做什么,但您需要使用来执行需要添加这样的值的操作类型

以下是一个例子:

scala> val rdd = spark.sparkContext.parallelize(Seq(
     |         (1, Array(2.0,5.0,6.3)),
     |         (5, Array(1.0,3.3,9.5)),
     |         (1, Array(5.0,4.2,3.1)),
     |         (2, Array(9.6,6.3,2.3)),
     |         (1, Array(8.5,2.5,1.2)),
     |         (5, Array(6.0,2.4,7.8)),
     |         (2, Array(7.8,9.1,4.2))
     |       )
     | )
rdd: org.apache.spark.rdd.RDD[(Int, Array[Double])] = ParallelCollectionRDD[83] at parallelize at <console>:24

scala> val accum = sc.longAccumulator("My Accumulator")
accum: org.apache.spark.util.LongAccumulator = LongAccumulator(id: 46181, name: Some(My Accumulator), value: 0)

scala> rdd.foreach { x => if(x._1 == 1) accum.add(1) }

scala> accum.value
res38: Long = 3

您也可以使用
countByKey
,但在使用大数据集时要避免使用它。

我不确定您在做什么,但您需要使用它来执行需要这样添加值的操作类型

OR You can do achieve your problem in this way also:
class ABC extends Serializable {
        def demo(data_new : RDD[(Int ,Array[Double])]): Unit ={
            var new_value = 0
            data_new.coalesce(1).map(x => {
                if(x._1 == 1)
                  var key = x._1
             (key, 1)
            }).reduceByKey(_ + _)

        }
     println("Outside-->" +demo(data_new))
    }
以下是一个例子:

scala> val rdd = spark.sparkContext.parallelize(Seq(
     |         (1, Array(2.0,5.0,6.3)),
     |         (5, Array(1.0,3.3,9.5)),
     |         (1, Array(5.0,4.2,3.1)),
     |         (2, Array(9.6,6.3,2.3)),
     |         (1, Array(8.5,2.5,1.2)),
     |         (5, Array(6.0,2.4,7.8)),
     |         (2, Array(7.8,9.1,4.2))
     |       )
     | )
rdd: org.apache.spark.rdd.RDD[(Int, Array[Double])] = ParallelCollectionRDD[83] at parallelize at <console>:24

scala> val accum = sc.longAccumulator("My Accumulator")
accum: org.apache.spark.util.LongAccumulator = LongAccumulator(id: 46181, name: Some(My Accumulator), value: 0)

scala> rdd.foreach { x => if(x._1 == 1) accum.add(1) }

scala> accum.value
res38: Long = 3


您也可以使用
countByKey
,但要避免使用大数据集。

您是否正在尝试计算每个键的出现次数?如果是这样,那么还有更好的方法。谢谢你的回复。实际上我想知道如何更新全局变量。这只是一个例子,我已经尝试将类ABC()更改为对象ABC()。我得到了更新的值。那为什么不可能上课呢。全局变量声明中的类和对象之间有什么区别?您是否正在尝试计算每个键的出现次数?如果是这样,那么还有更好的方法。谢谢你的回复。实际上我想知道如何更新全局变量。这只是一个例子,我已经尝试将类ABC()更改为对象ABC()。我得到了更新的值。那为什么不可能上课呢。全局变量中的类和对象有什么区别declaration@T.Gaw真的。顺便说一句,我不知道OP想要什么:我实际上从来没有使用过累加器。但是我们不能说你不应该使用它们。但您的评论显然是正确的:确定可能不应该,但应意识到可能的任务重新启动确定,修改版本,以前的评论不能编辑:只有当您意识到任务重新启动时,才应在转换中使用累加器:
仅用于内部操作执行的累加器更新,Spark保证每个任务对累加器的更新只应用一次,即重新启动的任务不会更新值。在转换过程中,用户应该意识到,如果重新执行任务或作业阶段,每个任务的更新可能会被应用多次。
@T.Gawęda。顺便说一句,我不知道OP想要什么:我实际上从来没有使用过累加器。但是我们不能说你不应该使用它们。但您的评论显然是正确的:确定可能不应该,但应意识到可能的任务重新启动确定,修改版本,以前的评论不能编辑:只有当您意识到任务重新启动时,才应在转换中使用累加器:
仅用于内部操作执行的累加器更新,Spark保证每个任务对累加器的更新只应用一次,即重新启动的任务不会更新值。在转换过程中,用户应注意,如果重新执行任务或作业阶段,每个任务的更新可能会应用多次。
感谢您的回复。实际上我想知道如何更新全局变量。这只是一个示例。您可以添加一个真正的实现,而不是示例。我已尝试将类ABC()更改为对象ABC()。我得到了更新的值。那为什么不可能上课呢。全局变量声明中类和对象的区别是什么谢谢你的回答。实际上我想知道如何更新全局变量。这只是一个示例。您可以添加一个真正的实现,而不是示例。我已尝试将类ABC()更改为对象ABC()。我得到了更新的值。那为什么不可能上课呢。在全局变量声明中,类和对象之间有什么区别
OR You can do achieve your problem in this way also:
class ABC extends Serializable {
        def demo(data_new : RDD[(Int ,Array[Double])]): Unit ={
            var new_value = 0
            data_new.coalesce(1).map(x => {
                if(x._1 == 1)
                  var key = x._1
             (key, 1)
            }).reduceByKey(_ + _)

        }
     println("Outside-->" +demo(data_new))
    }