热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

优雅解决SparkApplicationjar包冲突问题

前言当我们开发的SparkApplication变得越来越复杂,依赖的jar包越来越多时,难免会碰到jar包冲突的问题。举个例子:我们的业务代码用到了一个第三方库,好比:guava

前言

当我们开发的Spark Application变得越来越复杂,依赖的jar包越来越多时,难免会碰到jar包冲突的问题。

举个例子:

  1. 我们的业务代码用到了一个第三方库,好比:guava(虽然好用,但是版本间的兼容性差的一坨翔)
  2. Spark本身也依赖了guava,但是和业务代码中依赖的guava版本不同

这种情况下,把我们的Spark Application提交到集群里执行,很有可能因为版本问题导致运行出错。

大家都知道,JVM的ClassLoader加载类的时候,同一个ClassLoader加载的类,如果出现重复,只有第一个会被加载,后面重复的类会被忽略掉。

就我们的例子来说,整个Spark Application会优先加载Spark jars目录下的guava包,那么我们的业务代码自然很有可能受到影响了。

虽然Spark提供了一个spark.driver.userClassPathFirst配置,用来解决这个问题,但这个实验性的参数用起来比较鸡肋。首先只能应用于cluster模式,另外,设定为ture的时候还有可能会影响Spark本身的依赖。总之,不能很好地解决jar包冲突的问题。

接下来,我们探讨一种更加优雅的解决方案。

对依赖包做shade处理

Java的一大优势,就是基于字节码,我们也可以动态修改字节码文件。我们可以将项目中依赖的jar包中的类名改掉。

还是以guava为例,guava包中的包名以com.google.common.*开头,我们将guava包及代码依赖中的包名全部改掉,如:my_guava.common.*,然后打包到一起,就可以解决包冲突的问题。这种处理的效果,看起来就像是我们不在依赖guava了,自然也就不会和Spark自带的guava包产生冲突了。

这种处理我们称之为:shade化。好在我们常用的包管理工具已经有了shade化的处理方案了。

基于sbt构建的项目

修改项目目录的project/plugins.sbt,添加assembly插件addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")

然后修改build.sbt在项目配置中添加以下设置:

assemblyShadeRules in assembly := Seq(
// 处理guava版本和spark自带guava包版本冲突问题
ShadeRule.rename("com.google.common.**" -> "my_guava.common.@1").inAll
)

sbt的assembly插件会将项目中所有的依赖都打包到一起,通常情况下我们的集群中已经有Spark的部署包了,不需要把Spark的包也打进来。

我们在添加依赖的时候通过
provided将其排除掉即可,如下:

libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "2.3.1" % "provided"
)

最后执行sbt assembly打包就可以了。

基于maven构建的项目

maven项目可以通过maven-shade-plugin插件,将有冲突的jar包shade化。

关键代码如下:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
...



org.apache.maven.plugins
maven-shade-plugin
3.1.0


package

shade




com.google.common
my_guava.common




*:*

META-INF/maven/**









最后通过mvn package打包项目就可以了。

验证

为了确保,我们确实shade化成功了,可以通过JD-GUI工具将打好的jar包反编译,正常情况下应该看不到com.google.common开头的包,而是包含my_guava.common开头的的包。如下图所示:

《优雅解决Spark Application jar包冲突问题》
《优雅解决Spark Application jar包冲突问题》

验证没问题的话就可以安心地提交到集群运行了。

结语

通过shade化第三方jar包,避免jar包版本冲突问题是个通用的解决方案,不仅适用于Spark Application,其他Java项目依然适用。

最近关注了下HBase 2.0,发现HBase也引入了shade机制,这样大家使用HBase时,就不用担心项目的第三方包跟HBase冲突的问题了。

相比之下Spark没有shade化,出现冲突问题,只能用户侧自己解决了😪。


推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
author-avatar
yukolin1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有