① Apache Zeppelin 迁移 - Jar 包冲突解决与思考
最近整个公司大数据集群迁移(cdh -> ambri hdp),随之 Zeppelin 也需要迁移,由于各个组件版本有变化,且 Zeppelin 源码是有过改动的,迁移起来很麻烦。经过一周的折腾,终于把 Zeppelin 从 cdh 环境迁移至 hdp 环境。同时,在解决问题期间,对 Java 类加载,jar 冲突问题有了更进一步的认识。
版本有所变化,当然得重新编译 Zeppelin ,指定下 spark hadoop 大版本,重新编译:
经过配置参数修改,迁移过去 hive 没问题,spark 运行报错,经过一周的折腾终于解决,主要是版本依赖冲突问题。
现象:跑 spark sql 报 NoSuchMethodError 错误如下:
连 hive metastore 后调用 close() 方法, FacebookService( from: libfb303.jar ) 最终调用 TClient.sendBaseOneway ( to: libthrift.jar )
查看 libthrift 源码, 0.9.3 版本有 sendBaseOneway , 而 0.9.2 版本没有。
结论: libfb303.jar 的 facebookservice 调用了 libthrift 0.9.3 版本的中的方法,而 JVM 加载了 0.9.2 版本, 导致 NoSuchMethodError。
查看 zeppelin 源码, zeppelin-spark*.jar , zeppelin-spark-dependencices*.jar 都 shaded 了 libthrift 这个 jar 包。
打包信息如下:
jar 所在目录:
这里也有一个取巧的方法,将 jar 包解压删除 thrift 并重新打包。通过 linux 下 jar 命令即可完成。
如果深入理解 Java 类加载机制,jar包冲突相关原因,对定位解决这类问题有很大的帮助 。
一般来说遇到: ClassNotFoundExpection , NoClassDefFoundError 和 NoSuchMethodError ,有可能是包冲突造成的。
先来解释下这个三个问题的区别 [1]:
读完这个 重新看待Jar包冲突问题及解决方案 [3]收获良多,总结部分笔记,对于冲突,存在两个场景:
这两个场景的存在,会导致 JVM 加载到了错误的类,导致与预期场景不一致出现上面描述的错误等 ,导致出现 ClassNotFoundExpection , NoClassDefFoundError 和 NoSuchMethodError 等异常。
因为 maven 的传递依赖机制,maven 引入依赖类似于图的遍历,从子往父溯源,引入所有相关依赖。这样为开发节省了效率,但同时可能引入不同版本的 jar 包,导致在运行时出现包冲突。存在多个依赖,maven 具体选择引入哪个依赖,规范来源于仲裁机制,仲裁机制如下:
常见的解决依赖冲突的办法有两个:
下面这段配置取自 Zeppelin pom,声明选择的依赖的 avro 版本,同时排除了部分依赖 如 netty。
还有一种冲突是同样的类,出现在不同的包里面,例如 A 和 B 包都有类 C,JVM 在加载 C 的时候到底是选择 A 还是 B。这个选择取决于:
如果遇到 ClassNotFoundExpection , NoClassDefFoundError 和 NoSuchMethodError ,有可能是包冲突造成的。
[1] https://stackoverflow.com/questions/1457863/what-causes-and-what-are-the-differences-between-noclassdeffounderror-and-classn/1457879#1457879
[2] classnotfoundexception-vs-noclassdeffounderror
[3] 重新看待Jar包冲突问题及解决方案
② 怎样在spark单机上编写运行scala程序
使用Scala写一个测试代码:
object Test {
def main(args: Array[String]): Unit = {
println("hello world")
}
}
就把这个Test视为类,项目组织结构如:
③ spark1.3编译出错,求解决方法
把 pom.xml文件中的scalastyle的相关改成false
<groupId>org.scalastyle</groupId>
<artifactId>scalastyle-maven-plugin</artifactId>
<version>0.4.0</version>
<configuration>
<verbose>false</verbose>
<failOnViolation>false</failOnViolation>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<failOnWarning>false</failOnWarning>
④ spark的开发环境应该是怎样的
indows下spark开发环境配置
特注:windows下开发spark不需要在本地安装hadoop,但是需要winutils.exe、hadoop.dll等文件,前提是你已经安装了eclipse、maven、jdk等软件
spark支持jdk版本建议是1.8及以上,如果开发spark建议将jdk编译版本设置为1.8
我选择的spark是spark-1.4.0-bin-hadoop2.6.tgz,故以该版本为例
第一步:下载spark-1.4.0-bin-hadoop2.6.tgz到本地,并解压在本地目录
⑤ Hudi + Spark3入门第一课
欢迎访问 我的博客
这两个包不用自己编译,可以从maven 中央仓库 获取,(页面很不好找,hudi得把仓库类目梳理一下了)贴一下。
使用上述预编译的包,就省略自己编译的过程了。
官网发布的支持矩阵:
Spark 3 Support Matrix
可以看到hudi 0.10版本默认构建出来是spark3.1的,也可以构建spark3.0的。
⑥ spark源码二次开发难吗
spark源码二次开发不难。掌握了源码编译,就具备了对Spark进行二次开发的基本条件了,要修改Spark源码,进行二次开发,那么就得从官网下载指定版本的源码,导入ide开发环境,进行源码的修改。接着修改完了。