如何构建一个正常工作的GraphX Spark应用程序以在EMR上运行?

时间:2015-04-15 16:11:48

标签: amazon-web-services amazon-ec2 apache-spark emr spark-graphx

我有一个用Spark GraphX(Scala 2.10)和其他Spark库编写的脚本来处理Wikipedia转储的PageRank分数并检索最佳结果。我可以通过将脚本放在examples文件夹中并在其所需的依赖项中进行操作来使脚本在本地运行。但我找不到将其编译为应用程序的方法,以便它可以在Amazon EC2上运行。

我试过了:

  • 编译整个Spark项目的胖jar,我的脚本作为一个新类,并从示例中运行该类:org.apache.spark.examples.graphx.PageRankGraphX(非常' roundabout'路径成功编译和群集上的最终失败 - SparkException:应用程序以失败状态完成。这是我在本地设置上取得最大成功的方法,但我认为我的方法并不标准。
  • 将脚本添加到源代码中的另一个库,例如GraphX(这使得无法编译 - 找不到很多库项,例如:java.lang.NoClassDefFoundError:com / google / common / util / concurrent / ThreadFactoryBuilder)
  • 在没有Spark源的情况下构建一个全新的项目,在sbt文件中仅添加我的脚本作为源代码以及Spark依赖项(例如Spark核心,Spark流,Spark GraphX等) - 这会编译,但是当我尝试在运行时运行应用程序它失败了,因为几乎每个依赖项都缺少代码(例如ClassDefNotFoundException:Scala / Serializer)。

我希望有人有一些易于遵循的说明,如何运行一个用GraphX编写的独立jar,它将在Amazon EMR上处理。我的整个脚本发布在下面 - 如果这是您的,那么您将如何在AWS上运行并生成输出文件?我不认为任何细节在这里太基础了:

  • 使用我的脚本作为新类来构建整个下载的Spark项目是否正确?如果是这样,在Spark源代码中,脚本属于哪个文件夹?
  • 或者是在一个全新项目中构建它的正确方法?如果是这样,如何确保sbt包含运行时可能需要的每个依赖项,以便应用程序能够正确运行?
  • 否则,如果这些都不是正确的,我应该如何处理我的脚本在Amazon WS EMR上成功运行它?我之前在MR中运行了集群项目,没有遇到这种麻烦。

我尝试运行的脚本如下 - 我可以肯定地证明,当所有依赖项都正确编译时,它的工作原理应该正常 - 但是,我编译的版本在EMR的实际工作中仍然失败。

package org.apache.spark.graphx

import java.io._
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.graphx.lib.PageRank
import org.apache.spark.rdd.RDD

object PageRankGraph extends Serializable {

  def hashId(str: String): Long = {

    val bytes = MessageDigest.getInstance("MD5").digest(str.getBytes(StandardCharsets.UTF_8))
    (bytes(0) & 0xFFL) |
      ((bytes(1) & 0xFFL) << 8) |
      ((bytes(2) & 0xFFL) << 16) |
      ((bytes(3) & 0xFFL) << 24) |
      ((bytes(4) & 0xFFL) << 32) |
      ((bytes(5) & 0xFFL) << 40) |
      ((bytes(6) & 0xFFL) << 48) |
      ((bytes(7) & 0xFFL) << 56)
  }

  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
      .setAppName("WikipediaGraphXPageRank")
      .setMaster(args(5))
      .set("spark.executor.memory","1g")

    val sc = new SparkContext(sparkConf)
    val topics: RDD[String] = (sc.textFile(args(0))
      .map(line => line.split("\t")).map(parts => (parts.head)))

    val vertices = topics map (topic => hashId(topic) -> topic)
    val uniqueHashes = vertices.map(_._1).countByValue()
    val uniqueTopics = vertices.map(_._2).countByValue()
    uniqueHashes.size == uniqueTopics.size

    val linksall = (sc.textFile(args(0))).map(l => l.split("\t"))
    val links = for (l <- linksall; l2 <- l(2).split(",")) yield (l(0), l2)

    val edges = for (l <- links) yield Edge(hashId(l._1), hashId(l._2), 0)
    val graph = Graph(vertices, edges, "").cache()

    graph.vertices.count

    if (args(4).toInt == 1) graph.partitionBy(PartitionStrategy.RandomVertexCut)
    else if (args(4).toInt == 2) graph.partitionBy(PartitionStrategy.EdgePartition2D)
    else if (args(4).toInt == 3) graph.partitionBy(PartitionStrategy.CanonicalRandomVertexCut)
    else graph.partitionBy(PartitionStrategy.EdgePartition1D)

    var prGraph = PageRank.run(graph, args(2).toInt, args(3).toDouble)

    val titleAndPrGraph = graph.outerJoinVertices(prGraph.vertices) {
      (v, title, rank) => (rank.getOrElse(0.0), title)
    }

    val pw = new PrintWriter(new File(args(1)))

    titleAndPrGraph.vertices.top(100) {
      Ordering.by((entry: (VertexId, (Double, String))) => entry._2._1)
    }.foreach(t =>
      if(t._2._2 != "") {
      pw.write("\nTitle: " + t._2._2 + " : " + t._2._1 + "\n")
    })

    pw.close()
  }

}

任何能够解决这个问题的光都会非常有帮助。就像我说的那样,我已经发现几乎每个教程和指南都缺乏详细程度我已经读过这个,所以你能负担得越多越好(PS我在Windows上尝试了以上所有内容)机)。

0 个答案:

没有答案