强制分区存储在特定执行程序

时间:2017-03-03 00:34:50

标签: java scala apache-spark rdd shuffle

我有5个parditions-RDD和5个工人/执行者。 如何让Spark在不同的工作人员(ip)上保存每个RDD的分区?

如果我说Spark可以在一个worker上保存几个分区,而在其他worker上保存0个分区,我是对的吗?我可以指定分区数量,但Spark仍然可以在单个节点上缓存所有内容。

复制不是一种选择,因为RDD很大。

我找到的解决方法

getPreferredLocations

RDD' getPreferredLocations方法不提供100%保证该分区将存储在指定节点上。 Spark会在spark.locality.wait期间尝试,但之后Spark会将分区缓存在不同的节点上。

As a workarround,您可以将非常高的值设置为spark.locality.wait并覆盖getPreferredLocations。坏消息 - 你不能用Java做到这一点,你需要编写Scala代码。至少Scala内部包含Java代码。即:

class NodeAffinityRDD[U: ClassTag](prev: RDD[U]) extends RDD[U](prev) {

  val nodeIPs = Array("192.168.2.140","192.168.2.157","192.168.2.77")

  override def getPreferredLocations(split: Partition): Seq[String] =
    Seq(nodeIPs(split.index % nodeIPs.length))
}

SparkContext的makeRDD

SparkContext has makeRDD method。这种方法缺乏文献记载。据我了解,我可以指定首选位置,而不是将高值设置为spark.locality.wait。坏消息 - 首选位置will be discarded on the first shuffle/join/cogroup operation

如果某些节点不可用,这两种方法都有过高spark.locality.wait的缺点会导致群集结束。

P.S。更多背景

我有多达10,000个sales-XXX.parquet个文件,每个文件代表不同地区不同商品的销售额。每个sales-XXX.parquet可能会从几KB到几GB不等。所有sales-XXX.parquet一起在HDFS上可能需要数十或数百GB。 我需要全文搜索所有销售。我必须用Lucene逐个索引每个sales-XXX.parquet。现在我有两个选择:

  1. 在Spark中保留Lucene索引。已经有solution for this,但看起来很可疑。 有没有更好的解决方案?
  2. 将Lucene索引保留在本地文件系统中。比我可以map-reduce每个worker的索引查找结果。但是这种方法要求每个工作节点保持相同数量的数据。 我如何确保Spark在每个工作节点上保留相同数量的数据?

0 个答案:

没有答案