Scala 2.11 Spark 2.0 hortonworks-spark / shc sbt assemby

时间:2016-12-07 14:18:03

标签: scala apache-spark sbt hbase apache-spark-sql

我尝试使用hortonworks-spark/shc组装Scala 2.11 Spark 2.0应用程序来访问hbase。

依赖关系设置看起来很简单:

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "2.0.2" % "provided",
  "com.hortonworks" % "shc-core" % "1.0.1-2.0-s_2.11"
)

当我尝试在Fat jar中组装应用程序时出现问题,因为有许多不同版本的瞬态依赖项,然后程序集插件会抛出重复错误。一个例子:

deduplicate: different file contents found in the following:
[error] /home/search/.ivy2/cache/org.mortbay.jetty/jsp-2.1/jars/jsp-2.1-6.1.14.jar:org/apache/jasper/xmlparser/XMLString.class
[error] /home/search/.ivy2/cache/tomcat/jasper-compiler/jars/jasper-compiler-5.5.23.jar:org/apache/jasper/xmlparser/XMLString.class

另外,我不知道它是否正确包含在jar依赖项中,如org.apache.hbase:hbase-server:1.1.2

所以,基本上,问题是:任何人都知道使用这个库和sbt组装Scala Spark应用程序的正确方法并且可以提供一个示例吗? (也许可以在hortonworks-spark/shc

的文档中添加它

注意:hortonworks-spark/shc中不包含spark-packages,因此如果不包含jar的本地副本,我就不能使用--packages选项。我正在使用EMR,因此我没有预先配置的集群来复制jar而不会增加部署的复杂性。

3 个答案:

答案 0 :(得分:0)

您应该指定Readme中提到的mergeStrategy。并且您可以在spark节点上提供公共库,而不是每次都将它们包含在fat.jar中。这样做的好方法是将它们上传到每个worker上并添加到classpath。

答案 1 :(得分:0)

正如您所见,两个不同的罐子正在使用jasper-xmlparser。所以复制品。您可以从其中一个中排除引用,如下所示

例如: libraryDependencies + =" org.apache.hbase" %" hbase-server" %" 0.98.12-hadoop2" excludeAll ExclusionRule(organization =" org.mortbay.jetty")

关于将所有依赖项添加到fat jar中,至少是spark应用程序,这是处理jar程序集的建议方法。 最常见的jar(如spark,hbase等)可以成为边缘节点上的类路径的一部分,也可以是您正在运行的节点的一部分。任何其他特定的罐子,可以是超级罐子的一部分。你可以按照提供的方式制作spark / hbase罐子。

核心是,以下内容可以帮助您进行基本操作。

libraryDependencies += "org.apache.hbase" % "hbase-client" % "0.98.12-hadoop2" // % "provided"
libraryDependencies += "org.apache.hbase" % "hbase-common" % "0.98.12-hadoop2"  //% "provided"
libraryDependencies += "org.apache.hbase" % "hbase-server" % "0.98.12-hadoop2" excludeAll ExclusionRule(organization = "org.mortbay.jetty")

答案 2 :(得分:0)

您必须在build.sbt中提供mergeStrategy,

它看起来像这样,

assemblyMergeStrategy in assembly := {
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard
    case "reference.conf" => MergeStrategy.concat
    case x => MergeStrategy.first
}

在此示例中,我指定了 MergeStrategy.first 。其他选项很少,例如 MergeStrategy.last MergeStrategy.concat

MergeStrategy.first意味着它将为给定的依赖项选择它看到的第一个jar来创建一个超级jar。

对于某些情况,它可能无效,如果是这种情况请尝试 MergeStrategy.last也。