我尝试使用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而不会增加部署的复杂性。
答案 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也。