在火花中,广播如何运作?

时间:2016-11-18 20:30:18

标签: apache-spark hadoop2 bigdata

这是一个非常简单的问题:在spark中,broadcast可用于有效地将变量发送给执行程序。这是如何工作的?

更确切地说:

  • 何时发送值:我只要拨打broadcast,或者何时使用这些值?
  • 数据的确切位置是:发送给所有执行者,还是只发送给需要它的那些执行者?
  • 数据存储在哪里?在内存中,还是在磁盘上?
  • 访问简单变量和广播变量的方式有何不同?当我调用.value方法时,幕后会发生什么?

2 个答案:

答案 0 :(得分:11)

简短回答

  • 值在执行程序中第一次需要时发送。调用sc.broadcast(variable)时不会发送任何内容。
  • 数据仅发送到包含需要它的执行程序的节点。
  • 数据存储在内存中。如果内存不足,则使用磁盘。
  • 是的,访问本地变量和广播变量之间存在很大差异。广告变量必须在第一次访问时下载。

答案很长

答案来自Spark的来源TorrentBroadcast.scala

  1. 调用sc.broadcast时,将从TorrentBroadcast实例化一个新的BroadcastFactory.scala对象。在writeBlocks()中发生以下情况,在初始化TorrentBroadcast对象时调用:

    1. 使用MEMORY_AND_DISK策略在本地对对象进行非序列化缓存。
    2. 序列化。
    3. 序列化版本分为4Mb块,压缩 [0] ,并保存本地 [1]
  2. 创建新的执行程序时,它们只有轻量级TorrentBroadcast对象,它只包含广播对象的标识符及其块数。

  3. TorrentBroadcast对象具有包含其值的惰性 [2] 属性。调用value方法时,将返回此惰性属性。因此,第一次在任务上调用此值函数时,会发生以下情况:

    1. 以随机顺序,从本地块管理器中取出块并解压缩。
    2. 如果它们不在本地块管理器中,则在块管理器上调用getRemoteBytes来获取它们。 仅在那时发生网络流量
    3. 如果该块未在本地存在,则使用MEMORY_AND_DISK_SER进行缓存。
  4. [0] 默认情况下压缩为lz4。 This can be tuned

    [1] 这些块使用block manager存储在本地MEMORY_AND_DISK_SER中,这意味着它溢出了不适合的分区内存到磁盘。每个块具有唯一标识符,该标识符根据广播变量的标识符及其偏移量计算。块can be configured的大小;它默认为4Mb。

    [2] scala中的 lazy val是一个变量,其值在第一次访问时进行评估,然后进行缓存。 See the documentation

答案 1 :(得分:2)

  • 广播后立即
  • 使用torrent协议发送给所有执行程序,但仅在需要时加载
  • 一旦加载的变量存储在内存中反序列化
  • 它:

    • 验证广播没有被销毁
    • 从blockManager
    • 延迟加载变量