有话要说
针对一个老毛病:有些错误屡犯屡改,屡改屡犯,没有引起根本上的注意,或者没有从源头理解错误发生的底层原理,导致做很多无用功。
总结历史,并从中吸取教训,减少无用功造成的时间浪费。特此将从目前遇到的spark问题全部记录在这里,搞清楚问题,自信向前。
问题汇总
问题1:spark-hive classes are not found
概述:
1 | Exception in thread "main" java.lang.IllegalArgumentException: Unable to instantiate SparkSession with Hive support because Hive classes are not found. |
场景:
在本地调试spark程序,连接虚拟机上的集群,尝试执行sparkSQL时,启动任务就报错。
原理:
缺少sparkSQL连接hive的必要和依赖jar包,添加相应的依赖包即可。
办法:
1 | 在项目/模块的pom.xml中添加相关的spark-hive依赖jar包。 |
问题2:Spark Local 模式写 Hive,user=xialinsheng
概述:
1 | Caused by: org.apache.hadoop.security.AccessControlException: Permission denied: user=xialinsheng, access=WRITE, inode="/user/hive/warehouse/xls002":hadoop:supergroup:drwxr-xr-x |
场景:
Spark Local 模式连接集群,对 Hadoop 无操作权限。
原理:
Spark 在 Local 模式时,如果在本地机器没有设定 HADOOP_USER_NAME ,程序会使用本地的机器名作为 HADOOP_USER_NAME ,这就导致在 Hadoop 集群中无法识别该用户名,从而没权限操作 Hadoop 。
获取 HADOOP_USER_NAME 的核心源码如下:
1 | if (!isSecurityEnabled() && (user == null)) { |
从源码可知,要想解决该问题,只要在本机的环境变量中添加 HADOOP_USER_NAME = Hadoop (对 Hadoop 集群有操作权限的用户,具体视自身情况而定。)
参考博客:点我了解更多
解决:
因为我的需求只是在测试的时候会使用 Local 模式连接集群上的 Hive 表,因而我的处理方式则是在程序代码中指定 :
1 | System.setProperty("HADOOP_USER_NAME","Hadoop有权限的用户名"); |
问题3:javax.servlet.FilterRegistration
概述:
在idea上运行spark程序时,出现以下信息:
1 | Spark error class "javax.servlet.FilterRegistration"'s signer information does not match signer information of other classes in the same package |
如图:
原理:
包冲突导致。
解决:
按照以下步骤操作:
- 右键模块项目
- Open Module Settings
- 选择Dependencies
- 找到 javax.servlet:servlet-api:xx
- 移动到列表的最末端
- Apply,Ok
如下图: