检测到Guava问题#1635,表明正在使用不低于16.01版本的Guava。

6

我在EMR上运行Spark作业,并使用DataStax连接器连接到Cassandra集群。我遇到了关于Guava jar的问题,请查看以下详细信息 我正在使用以下Cassandra依赖项

cqlsh 5.0.1 | Cassandra 3.0.1 | CQL spec 3.3.1 

在EMR 4.4上运行spark作业,使用以下Maven依赖项:
org.apache.spark spark-streaming_2.10 1.5.0
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.10</artifactId>
    <version>1.5.0</version>
</dependency>

<dependency>
    <groupId>org.apache.spark</groupId><dependency>
    <groupId>com.datastax.spark</groupId>
    <artifactId>spark-cassandra-connector_2.10</artifactId>
    <version>1.5.0</version>
</dependency>

    <artifactId>spark-streaming-kinesis-asl_2.10</artifactId>
    <version>1.5.0</version>
</dependency>

我在提交以下Spark作业时遇到了问题。
ava.lang.ExceptionInInitializerError
       at com.datastax.spark.connector.cql.DefaultConnectionFactory$.clusterBuilder(CassandraConnectionFactory.scala:35)
       at com.datastax.spark.connector.cql.DefaultConnectionFactory$.createCluster(CassandraConnectionFactory.scala:87)
       at com.datastax.spark.connector.cql.CassandraConnector$.com$datastax$spark$connector$cql$CassandraConnector$$createSession(CassandraConnector.scala:153)
       at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$2.apply(CassandraConnector.scala:148)
       at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$2.apply(CassandraConnector.scala:148)
       at com.datastax.spark.connector.cql.RefCountedCache.createNewValueAndKeys(RefCountedCache.scala:31)
      at com.datastax.spark.connector.cql.RefCountedCache.acquire(RefCountedCache.scala:56)
       at com.datastax.spark.connector.cql.CassandraConnector.openSession(CassandraConnector.scala:81)
       at ampush.event.process.core.CassandraServiceManagerImpl.getAdMetaInfo(CassandraServiceManagerImpl.java:158)
       at ampush.event.config.metric.processor.ScheduledEventAggregator$4.call(ScheduledEventAggregator.java:308)
       at ampush.event.config.metric.processor.ScheduledEventAggregator$4.call(ScheduledEventAggregator.java:290)
       at org.apache.spark.api.java.JavaRDDLike$$anonfun$foreachPartition$1.apply(JavaRDDLike.scala:222)
       at org.apache.spark.api.java.JavaRDDLike$$anonfun$foreachPartition$1.apply(JavaRDDLike.scala:222)
       at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$29.apply(RDD.scala:902)
       at org.apache.spark.rdd.RDD$$anonfun$foreachPartition$1$$anonfun$apply$29.apply(RDD.scala:902)
       at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1850)
       at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1850)
       at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
       at org.apache.spark.scheduler.Task.run(Task.scala:88)
       at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
       at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Detected Guava issue #1635 which indicates that a version of Guava less than 16.01 is in use.  This introduces codec resolution issues and potentially other incompatibility issues in the driver.  Please upgrade to Guava 16.01 or later.
       at com.datastax.driver.core.SanityChecks.checkGuava(SanityChecks.java:62)
       at com.datastax.driver.core.SanityChecks.check(SanityChecks.java:36)
       at com.datastax.driver.core.Cluster.<clinit>(Cluster.java:67)
       ... 23 more

请告诉我如何在这里管理Guava依赖项?

谢谢。


你的依赖块不完整。 - Adrian Shum
6个回答

10

另一种解决方案,进入目录

spark/jars

重命名 guava-14.0.1.jar 然后像图片中那样复制 guava-19.0.jar:

enter image description here


2
请注意,Guava 20不适用于此。虽然Guava 19可以使用。 - Eric Finn
这是一个很棒的技巧! - Tony Fraser
重命名旧的jar文件并添加新的文件对我没有起作用(spark 2.4.0)。 删除旧的jar文件解决了问题。 - Bogdan Iordache

5
我曾经遇到过同样的问题,并通过使用Maven Shade插件来隐藏Cassandra连接器带来的Guava版本来解决它。
由于我遇到了Spark尝试从非遮蔽的Guava Present类型转换为遮蔽的Optional类型而导致的问题,因此我需要显式地排除Optional、Present和Absent类。我不确定这是否会在以后造成任何问题,但现在对我来说似乎是有效的。
您可以将以下内容添加到pom.xml文件的部分中:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>
                    shade
                </goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <minimizeJar>true</minimizeJar>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <shadedClassifierName>fat</shadedClassifierName>

        <relocations>
            <relocation>
                <pattern>com.google</pattern>
                <shadedPattern>shaded.guava</shadedPattern>
                <includes>
                    <include>com.google.**</include>
                </includes>

                <excludes>
                    <exclude>com.google.common.base.Optional</exclude>
                    <exclude>com.google.common.base.Absent</exclude>
                    <exclude>com.google.common.base.Present</exclude>
                </excludes>
            </relocation>
        </relocations>

        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </filter>
        </filters>

    </configuration>
</plugin>

1
这并不能解决问题。原因在于我们的部署平台EMR。EMR使用构建Spark默认类路径的方式是在类路径中使用小于16版本的guava,这是因为它拉取了仍然旧的EMR 4.2\4.4\4.6的Hadoop库。我通过向EMR添加引导过程来覆盖默认的Spark类路径以更新我的问题。 - Karn_way
我确认这对我在Spark Standalone v1.5.2集群和Spark Cassandra连接器v1.5.1上的问题进行了修复。谢谢。 - Alexis Seigneurin

3

当我使用Spark(Java)从Cassandra表中检索记录时,遇到了同样的问题。

请使用find命令检查Hadoop和Spark集群中使用的guava jar版本,并相应地更改它。

find / -name "guav*.jar"

否则,在spark-submit期间为驱动程序和执行程序分别添加外部的guava jar,使用spark.driver.extraClassPathspark.executor.extraClassPath
spark-submit --class com.my.spark.MySparkJob --master local --conf 'spark.yarn.executor.memoryOverhead=2048' --conf 'spark.cassandra.input.consistency.level=ONE' --conf 'spark.cassandra.output.consistency.level=ONE' --conf 'spark.dynamicAllocation.enabled=false' --conf "spark.driver.extraClassPath=lib/guava-19.0.jar" --conf "spark.executor.extraClassPath=lib/guava-19.0.jar" --total-executor-cores 15 --executor-memory 15g  --jars $(echo lib/*.jar | tr ' ' ',') target/my-sparkapp.jar

对我来说它有效。希望你也可以尝试一下。


2
只需在您的 POM 的 <dependencies> 块中添加以下内容:
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

(或者您喜欢的任何版本 > 16.0.1)


我正在查看链接https://groups.google.com/a/lists.datastax.com/forum/#!topic/spark-connector-user/HnTsWJkI5jo,其中提到Spark 1.5使用Guava 14,Cassandra驱动程序核心需要Guava 16。Spark Cassandra连接器会引发异常。因此,如何添加上述内容以解决我的问题可能是一个新手问题。谢谢。 - Karn_way
根据链接 https://github.com/datastax/spark-cassandra-connector,我正在使用1.5卡桑德拉连接器1.5、1.6(spak)3.0(卡桑德拉),但不确定为什么会出现问题。 - Karn_way
不确定你在问什么。如果你想知道为什么Maven解析了旧版本的Guava,你可以使用mvn dependency:tree命令,它会显示每个依赖项是如何被传递解析(或忽略)的。 - Adrian Shum
我找到了我在这里提到的问题的根本原因,它与EMR有关。在这里,Spark和Cassandra试图使用Guava 16,而EMR正在将旧的Hadoop库添加到Spark类路径中,从而获取旧的Guava 11。我正在与亚马逊的另一个请求一起努力解决这个问题。谢谢。 - Karn_way
哦,我希望那是这么容易的。对我来说,Spark 本身就有很多 jar 包。上面的截图几乎可以工作,但对于我们的 Spark 版本,我们有很多不同版本的 guava 分散在各个地方。最终我只是将它们全部过滤掉了,到处都是。我还像 @adri 一样将东西添加到类路径中。 - Tony Fraser
@TonyFraser 这就是 <dependencyManagement> 的用处。在你的父 POM 中声明 spark,并将有问题的依赖项排除在外。这样,继承自你的父 POM 的 POM,在声明 spark 作为依赖项时,将会排除那些有问题的依赖项。当然,你需要添加相应正确的依赖项。 - Adrian Shum

1
我能通过在外部添加guava 16.0.1 jar文件并使用以下配置值在Spark submit中指定class-path来解决这个问题:
--conf "spark.driver.extraClassPath=/guava-16.0.1.jar" --conf "spark.executor.extraClassPath=/guava-16.0.1.jar"
希望这能帮助遇到类似错误的人!

0

感谢Adrian的回复。

我使用的架构与线程上的其他人略有不同,但Guava问题仍然存在。 我正在使用spark 2.2和mesosphere。 在我们的开发环境中,我们使用sbt-native-packager生成我们的docker映像以传递到mesos。

事实证明,我们需要为spark submit执行程序使用不同的guava,而不是我们在驱动程序上运行的代码所需的guava。 这对我起作用了。

build.sbt

....
libraryDependencies ++= Seq(
  "com.google.guava" % "guava" % "19.0" force(),
  "org.apache.hadoop" % "hadoop-aws" % "2.7.3" excludeAll (
    ExclusionRule(organization = "org.apache.hadoop", name = "hadoop-common"), //this is for s3a
    ExclusionRule(organization = "com.google.guava",  name= "guava" )),
  "org.apache.spark" %% "spark-core" % "2.1.0"   excludeAll (
    ExclusionRule("org.glassfish.jersey.bundles.repackaged", name="jersey-guava"),
    ExclusionRule(organization = "com.google.guava",  name= "guava" )) ,
  "com.github.scopt" %% "scopt" % "3.7.0"  excludeAll (
    ExclusionRule("org.glassfish.jersey.bundles.repackaged", name="jersey-guava"),
    ExclusionRule(organization = "com.google.guava",  name= "guava" )) ,
  "com.datastax.spark" %% "spark-cassandra-connector" % "2.0.6",
...
dockerCommands ++= Seq(
...
  Cmd("RUN rm /opt/spark/dist/jars/guava-14.0.1.jar"),
  Cmd("RUN wget -q http://central.maven.org/maven2/com/google/guava/guava/23.0/guava-23.0.jar  -O /opt/spark/dist/jars/guava-23.0.jar")
...

当我试图将执行器上的guava 14替换为guava 16.0.1或19时,它仍然无法工作。Spark提交程序就死了。我的fat jar实际上是在驱动程序中使用的guava,我强制将其替换为19,但我的spark提交执行器必须替换为23。我确实尝试过替换为16和19,但Spark也在那里死了。

抱歉偏题了,但每次在我所有的谷歌搜索之后,这个问题总是出现。我希望这也能帮助其他SBT/mesos用户。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接