使用Apache Spark在节点之间共享数据

时间:2015-03-01 20:03:28

标签: scala apache-spark

以下是我启动Spark工作的方法:

./bin/spark-submit \
  --class MyDriver\
  --master spark://master:7077 \
  --executor-memory 845M \
  --deploy-mode client \
  ./bin/SparkJob-0.0.1-SNAPSHOT.jar

MyDriver使用:

访问spark上下文
val sc = new SparkContext(new SparkConf())

val dataFile= sc.textFile("/data/example.txt", 1)

为了在群集中运行它,我将文件"/data/example.txt"复制到群集中的所有节点。是否有一种机制使用Spark在节点之间共享此数据文件而无需手动复制它们?在这种情况下,我不认为我可以使用广播变量吗?

更新:

选项是使用专用文件服务器共享要处理的文件:val dataFile= sc.textFile("http://fileserver/data/example.txt", 1)

1 个答案:

答案 0 :(得分:1)

sc.textFile("/some/file.txt")读取以hdfs分发的文件,即:

  • /some/file.txt已经(已经)分成多个部分,每个部分分布在几台计算机上。
  • 并且每个worker / task读取文件的一部分。这很有用,因为您不需要自己管理哪个部分。

如果您已复制每个工作节点上的文件,则可以在所有任务中阅读它:

val myRdd = sc.parallelize(1 to 100) // 100 tasks
val fileReadEveryWhere = myRdd.map( read("/my/file.txt") )

并在某处实现了read(...)的代码。

否则,您还可以使用作为驱动程序种子的[广播变量]给所有工作人员:

val myObject = read("/my/file.txt")  // obj instantiated on driver node
val bdObj = sc.broadcast(myObject) 

val myRdd = sc.parallelize(1 to 100)
              .map{ i => 
                // use bdObj in task i, ex:
                bdObj.value.process(i)
              } 

在这种情况下,myObject应该是可序列化的,如果它不是太大则更好。

此外,方法read(...)在驱动程序计算机上运行。所以你只需要驱动程序上的文件。但是如果你不知道它是哪台机器(例如你使用spark-submit)那么该文件应该在所有机器上: - \。在这种情况下,访问某些DB或外部文件系统可能更好。