在Apache spark中,使用mapPartitions和组合使用广播变量和map之间的区别是什么

时间:2015-12-28 21:54:21

标签: java scala apache-spark

在Spark中,我们使用广播变量使每台机器只读变量的副本。我们通常在闭包之外创建一个广播变量(例如闭包所需的查找表)以提高性能。

我们还有一个名为mapPartitions的spark转换运算符,它试图实现相同的功能(使用共享变量来提高性能)。例如,在mapPartitions中,我们可以为每个分区共享数据库连接。

那么这两者有什么区别?我们可以互换地使用它来共享变量吗?

2 个答案:

答案 0 :(得分:4)

broadcast用于将对象发送到每个工作节点。该对象将在该节点上的所有分区之间共享(并且对于集群中的每个节点,值/即对象都是相同的)。广播的目标是在工作节点上的许多不同任务/分区中使用相同数据时节省网络成本。

相比之下,

mapPartitions是RDD上可用的方法,其工作方式与map类似,仅适用于分区。是的,您可以定义新对象,例如jdbc连接,然后对每个分区都是唯一的。但是,您不能在不同的分区之间共享它,更不用说在不同的节点之间共享它。

答案 1 :(得分:3)

虽然KrisP提供的答案突出了所有重要的差异,但我认为值得注意的是mapPartitions只是高级转换背后的低级构建块,而不是实现共享状态的方法。

虽然mapPartitions可用于使共享喜欢的状态显式,但技术上不共享(其生命周期仅限于mapPartitions闭包),并且还有其他方法可以实现它。特别是,在闭包内引用的变量在分区内共享。为了说明让我们与单身人士玩一点:

object DummySharedState {
  var i = 0L
  def get(x: Any) =  {
    i += 1L
    i
  }
}

sc.parallelize(1 to 100, 1).map(DummySharedState.get).max
// res3: Long = 100
sc.parallelize(1 to 100, 2).map(DummySharedState.get).max
// res4: Long = 50
sc.parallelize(1 to 100, 50).map(DummySharedState.get).max
// res5: Long = 2

和PySpark中的类似事情:

  • 单件模块dummy_shared_state.py

    i = 0
    def get(x):
        global i
        i += 1
        return i
    
  • 主脚本:

    from pyspark import SparkConf, SparkContext
    import dummy_shared_state
    
    master = "spark://..."
    conf = (SparkConf()
        .setMaster(master)
        .set("spark.python.worker.reuse", "false"))
    
    sc.addPyFile("dummy_shared_state.py")
    sc.parallelize(range(100), 1).map(dummy_shared_state.get).max()
    ## 100
    sc.parallelize(range(100), 2).map(dummy_shared_state.get).max()
    ## 50 
    

请注意,spark.python.worker.reuse选项设置为false。如果你保留默认值,你实际上会看到类似的东西:

sc.parallelize(range(100), 2).map(dummy_shared_state.get).max()
## 50
sc.parallelize(range(100), 2).map(dummy_shared_state.get).max()
## 100
sc.parallelize(range(100), 2).map(dummy_shared_state.get).max()
## 150

在一天结束时,你必须区分三种不同的东西:

  • 广播变量,旨在通过在工作人员上保留变量副本而不是随每项任务发送变量来减少网络流量和内存占用
  • 在闭包外部定义的变量和在闭包内引用的变量,必须随每个任务一起提供并为此任务共享
  • 在闭包内定义的变量

除此之外,还有一些与持久性解释器的使用相关的Python特定陷阱。

在变量生命周期中,mapfilter或其他转换)与mapPartitions之间仍然存在实际差异。