【问题标题】:Spark on YARN confilict with Elasticsearch TransportClient because of Guava library different versions由于 Guava 库版本不同,YARN 上的 Spark 与 Elasticsearch TransportClient 冲突
【发布时间】:2016-05-02 16:51:14
【问题描述】:

我想在 Google Cloud VM 集群上运行 Spark 作业,并且在地图操作中我需要对弹性搜索进行查询。我的问题是 Spark 和 Elastic Search 在 Guava 库上存在冲突,因为 Spark 使用的是 Guava 14 和 ES Guava 18。

我的问题是这个方法调用 com.google.common.util.concurrent.MoreExecutors.directExecutor(),存在于 Guava 18 中,但不存在于 Guava 14 中。

更详细地说,我正在尝试做的工作类似于以下内容。

 input.map(record=>{
    val client=openConnection()
    val newdata=client.query(record.someInfo)
      new record(newdata)
})

方法openConnection如下图

 public static TransportClient openConnection(String ipAddress, int ipPort) throws UnknownHostException {


    Settings settings = Settings.settingsBuilder().put("cluster.name", "elasticsearch").build();
    TransportClient client = TransportClient.builder().settings(settings).build().
            addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ipAddress), ipPort));

    return client;

}

我曾尝试通过在 sbt 文件中添加着色规则来强制 ES 使用 Guava 18,如下所示:

libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.0" % "provided"
libraryDependencies += "org.apache.spark" % "spark-graphx_2.10" % "1.6.0" % "provided"  ,
libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.6.0" % "provided" ,
libraryDependencies += "org.apache.spark" % "spark-streaming_2.10" % "1.6.0" % "

 libraryDependencies += "org.elasticsearch" % "elasticsearch" % "2.2.0",

 assemblyShadeRules in assembly :=Seq(
  ShadeRule.rename("com.google.common.*" -> "googlecommona.@1").
    inLibrary("org.elasticsearch" % "elasticsearch" % "2.2.0"))

但问题似乎仍然存在。 有没有办法解决这个冲突?

【问题讨论】:

  • 移除 Spark 的着色规则,因为这是一个提供的库。我还会尝试在 Guava 的重命名规则中使用两个星号 (**)。如果它仍然不起作用,请检查输出 jar 是否更改了包名称。为此,您可以将 jar 重命名为 zip,然后检查其中的目录。

标签: elasticsearch apache-spark guava


【解决方案1】:

您不能从提供的依赖项中排除过渡依赖项。 通过将其标记为provided,您告诉打包程序不要将其放入最终的 jar 中,因为您假设它已经在将要部署的类路径中。

所以你不能排除过渡依赖,因为整个依赖本身已经被排除了。

您的选择是:

  • 从 ElasticSearch 库中排除依赖:这意味着 ES 将使用 Spark 提供的 Guava,并且可能是不兼容的版本
  • 切换到具有相同 Guava 版本的 ElasticSearch 库(次要版本的差异大部分是兼容的,尽管您可能仍需要排除它)
  • 切换到与 ElasticSearch 具有相同 Guava 版本的 Spark 版本。
  • 使用阴影:现在可以在sbt-assembly SBT 插件中使用。阴影是类的重命名。您知道 ElasticSearch 和 Spark 都有自己的 Guava 版本,它们也将其作为依赖项包含在内。所以你指示SBT将ES提供的Guava重命名为Guava1,Spark提供的Guava重命名为Guava2,Spark对Guava的每一个引用都会重命名为Guava1,ES重命名为Guava2。

您可以阅读有关 sbt-assembly 着色here 的信息。

【讨论】:

  • 我已经按照你的指示做了,但问题仍然存在。
  • 感谢您的帮助!
【解决方案2】:

阴影就是答案:我在build.sbt 文件中添加了以下规则。

以下解决方案适用于使用 ElasticSearch TransportClient 类的 YARN 上的 SPARK 集群。

  assemblyShadeRules in assembly :=Seq(
      ShadeRule.rename("com.google.**" -> "googlecommona.@1").inAll
  )

为了完整起见,我附上整个 sbt 文件:

import sbt.ExclusionRule
import sbt.Keys._

lazy val root = (project in file(".")).
  settings(
  name := "scala_code",
  version := "1.0",
  scalaVersion := "2.10.6",
  conflictManager := ConflictManager.latestRevision,
  test in assembly := {},
  assemblyMergeStrategy in assembly := {
      case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
      case _ => MergeStrategy.first
  },

  parallelExecution in test := false,
  libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.10" % "2.6.5",
  libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.0" % "provided"  exclude("javax.servlet", "servlet-api"),
  libraryDependencies += "org.wikidata.wdtk" % "wdtk-datamodel" % "0.6.0" exclude ("com.fasterxml.jackson.core",  "jackson-annotations"),
  libraryDependencies += "org.apache.spark" % "spark-graphx_2.10" % "1.6.0" % "provided"  ,
  libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.6.0" % "provided" ,
  libraryDependencies += "org.apache.spark" % "spark-streaming_2.10" % "1.6.0" % "provided",
  libraryDependencies += "org.scalatest" % "scalatest_2.10" % "2.0" % "test",
 += "com.typesafe" % "config" % "1.2.1",
  libraryDependencies += "org.jsoup" % "jsoup" % "1.8.3",
  libraryDependencies += "org.elasticsearch" % "elasticsearch" % "2.2.0",// exclude("com.google.guava", "guava"),

  assemblyShadeRules in assembly :=Seq(
      ShadeRule.rename("com.google.**" -> "googlecommona.@1").inAll
  )

)

【讨论】:

    猜你喜欢
    • 2018-05-14
    • 2019-12-09
    • 2020-11-13
    • 2016-10-17
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    相关资源
    最近更新 更多