如何在Spark中定义全局读/写变量

时间:2016-04-04 11:36:24

标签: apache-spark

Spark有broadcast个变量(只读)和accumulator个变量,可以是节点更新,但不能读取。有没有办法 - 或者一种解决方法 - 来定义一个既可以更新又可以读取的变量?

这种读/写全局变量的一个要求是实现缓存。当文件作为rdd加载和处理时,执行计算。这些计算的结果 - 发生在并行运行的几个节点中 - 需要放在一个映射中,该映射具有正在处理的实体的一些属性的关键。当处理rdd中的后续实体时,将查询缓存。

Scala确实有ScalaCache,它是Google Guava等缓存实现的外观。但是如何在Spark应用程序中包含和访问这样的缓存呢?

缓存可以定义为驱动程序应用程序中的一个变量,用于创建SparkContext。但接下来会出现两个问题:

  • 由于网络开销,性能可能会很糟糕 在节点和驱动程序之间。
  • 据我了解,每个rdd都会传递一个变量副本 (在这种情况下缓存)当首次访问变量时 函数传递给rdd。每个rdd都拥有它自己的副本,而不是访问共享的全局变量。

实现和存储此类缓存的最佳方法是什么?

由于

1 个答案:

答案 0 :(得分:9)

嗯,这样做的最好办法就是不要这么做。通常,Spark处理模型不提供任何关于

的保证
  • 其中,
  • when,
  • 以什么顺序排列(当然不包括由谱系/ DAG定义的转换顺序)
  • 和多少次

执行了一段代码。此外,任何直接依赖于Spark架构的更新都不是精确的。

这些属性使Spark具有可扩展性和弹性,但同样地,这使得保持共享可变状态非常难以实现,并且大部分时间完全无用。

如果你想要的只是一个简单的缓存,那么你有多个选择:

  • 使用Tzach Zohar
  • Caching in Spark描述的方法之一
  • 使用本地缓存(每个JVM或执行程序线程)结合特定于应用程序的分区来保持本地化
  • 用于与外部系统通信使用独立于Spark的节点本地缓存(例如用于http请求的Nginx代理)

如果应用程序需要更复杂的通信,您可以尝试使用不同的消息传递工具来保持同步状态,但一般来说它需要复杂且可能很脆弱的代码。