Spark问题集

来源:互联网 发布:淘宝红包领取链接 编辑:程序博客网 时间:2024/05/16 19:45

1、java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.()V
在练习spark的过程中,有的同学遇到了这样的问题:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Exceptioninthread "main"java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.mapred.FileInputFormat
    at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:312)
    at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:199)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:237)
    at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:35)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:239)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:237)

问题原因:
一般来说这样的问题是因为 pom文件中有google的guava依赖吧?或者其他地方引用到了。 这个问题就是guava冲突了,版本不一致。所以大家优先去pom文件中排查。
解决办法:
比如2.3.1版本的elasticsearch在跟spark整合的过程中就会出现这个问题。我们可以注释掉elasticsearch的依赖,或者整合其他版本的。

2、Spark SQL: Error in query: undefined function
问题描述
如果你在Spark SQL上试图调用在HIVE注册的自定义函数(UDF)时,你可能会遇到这样的错误:

?
1
Spark SQL: Error inquery: undefined functionxxxxxx

这个问题发生在Spark 1.5.0, 1.5.1和1.5.2版本上,对此Spark官方有一个专门的bug report: https://issues.apache.org/jira/browse/SPARK-11191
简单说, 引起这个bug的原因是Spark SQL在与HIVE的(主要是Hive的元数据)交互上,在UDF方面有问题,导致Spark SQL无法正确的得到UDF的信息。针对这个问题最简单的解决方法当然是升级Spark,但是可能受制于其他因素,我们无法升级,这时就需要从别的途径来解决这个问题了。
解决方案
这里提供一个参考的解决方案,这个方案的思路是:绕过HIVE,直接在Spark上注册UDF。但这里有一个地方需要斟酌的地方,那就是在哪里和什么样的时机去注册UDF。
这里有一个假定,即:所有的SQL语句是抽离到专门的SQL文件中去,然后通过spark-sql -f /your/sql/file 的方式来执行的。
通常我们认为这是更加规范的做法,而不是在scala或java代码中去嵌入sql语句,那么在这样一个前提下,注册UDF的入口应该是spark-sql这个脚本的初始化环节中的某个地方,通过浏览Spark源码,我们得知spark-sql的入口是:

?
1
org.apache.spark.sql.hive.thriftserver.SparkSQLCLIDriver

而SparkSQLCLIDriver会通过

?
1
org.apache.spark.sql.hive.thriftserver.SparkSQLEnv#init

去初始化一个HiveContext, 这个HiveContext就是spark-sql启动后建立的hiveContext实例,同时也是后续SQL执行时使用的hiveContext实例,因此在这个实例的初始化方法就是我们注册我们的UDF的入口,我们可以在

?
1
hiveContext.setConf("spark.sql.hive.version", HiveContext.hiveExecutionVersion)

这一行之后添加注册UDF的代码:

?
1
hiveContext.udf.register("your_function_name",yourFunction _)

修改完成之后重新编译,把编译后的SparkSQLEnv的所有class文件更新到各个节点的spark的jar包中就可以了。


0 0