解决执行 spark.sql 时版本不兼容的一种方式

这篇具有很好参考价值的文章主要介绍了解决执行 spark.sql 时版本不兼容的一种方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景描述

hive 数据表的导入导出功能部分代码如下所示,使用 assemble 将 Java 程序和 spark 相关依赖一起打成 jar 包,最后 spark-submit 提交 jar 到集群执行。

public class SparkHiveApplication {

    public static void main(String[] args){

        long start = System.currentTimeMillis();
        String writeSql = "";
        SparkConf sparkConf = new SparkConf();

        for (String arg : args) {
            if (arg.startsWith("WriteSql=")) {
                writeSql = arg.replaceFirst("WriteSql=", "");
            }
        }

        SparkSession spark = SparkSession
                .builder()
                .appName("write data to hive table")
                .config(sparkConf)
                .enableHiveSupport()
                .getOrCreate();

        // LOAD DATA LOCAL INPATH '/path/to/file.csv' INTO TABLE target_table PARTITION (field='x')
        spark.sql(writeSql);

        long end = System.currentTimeMillis();
        System.out.println("cost time:" + (end - start));
    }
}
  <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-hive_2.11</artifactId>
      <version>2.4.8</version>
  </dependency>

在CDH6.3.2 集群(后面称CDH),当程序执行 spark.sql 导入本地磁盘 csv 数据到 hive 表时出现异常(如下),但导出表数据到本地磁盘、从 HDFS 导入导出功能却都是正常的。

Caused by: java.lang.IllegalArgumentException: Wrong FS: file:/input/data/training/csv_test1_1301125633652294217_1690451941587.csv, expected: hdfs://nameservice1
        at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:649)

查资料判定是 spark-hive_2.11 版本不兼容导致的,在调试的过程中陆续又出现异常(如下)

Exception in thread "main" org.apache.spark.sql.AnalysisException: org.apache.hadoop.hive.ql.metadata.HiveException: Unable to fetch table csv_test2. Invalid method name: 'get_table_req';
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/hive/ql/metadata/HiveException
        at java.lang.Class.getDeclaredConstructors0(Native Method)

最终使用 spark-hive_2.1.1: 2.4.0-cdh6.3.3 解决了最初的本地磁盘导入异常。

接着用包含 spark-hive_2.1.1: 2.4.0-cdh6.3.3 依赖的 jar 包在 CDP 集群(另一个大数据集群)执行导入导出时又抛了异常,修改依赖版本为 spark-hive_2.11: 2.4.8 ,异常解决。

java.lang.NoSuchMethodException: org.apache.hadoop.hive.ql.metadata.Hive.alterTable(java.lang.String, org.apache.hadoop.hive.ql.metadata.Table, org.apache.hadoop.hive.metastore.api.EnvironmentContext)

此时两个集群中参与导入导出的部分组件版本如下:

集群 spark hive Java 中的 spark-hive_2.1
CDH 3.0.x 2.1.1 2.4.0-cdh6.3.3
CDP 3.0.x 3.1.3 2.4.8

备注:导入导出操作采用 spark on k8s 方式执行,所以使用是镜像中的 spark 3.0 而非 CDH 、CDP 集群上安装的 spark。

异常原因分析

spark.sql 执行时要做三件事情:

  1. spark 首先创建 hiveMetaStoreClient 对象;
  2. 再调用 hiveMetaStoreClient 的方法去跟 CDH(CDP) 中的 hiveMetastoreServer 通信获取表相关元信息。
  3. 根据获取到的信息生成 sql 的执行计划,真正处理数据。

生成对象 jvm 首先需要通过全限定类名找到对应 Class 文件,通过反射的方式构造出对象再执行对象方法。问题也在这个地方:包名+类名相同,不同版本可能方法名、方法参数、方法内容不同,对应的出现 Invalid method name: 'get_table_req' java.lang.NoSuchMethodException 以及方法执行时抛出异常。

场景描述中更换依赖版本实际上是在找适配的 hiveMetastore 版本,并且让 jvm 率先加载到。2.4.0-cdh6.3.3 内部包含 hive-metastore:2.1.1-cdh6.3.3,2.4.8内部包含 hive-metastore:1.2.1spark2。

另一种解决方式

spark1.4.0 以后的版本支持和不同版本的 Hive Metastore 交互。列表贴的是 spark 3.4.1 兼容的 hive meatstore 版本 0.12.0 到 2.3.9 和 3.0.0 到 3.1.3。不同版本兼容可在官方文档查看。

解决执行 spark.sql 时版本不兼容的一种方式,大数据,spark,大数据,spark.sql

怎么配置和不同版本 hive metastore 交互?

(1)内置。spark 内置了 hive,如果应用程序 jar 包中也没有带,也没有外部指定时,默认使用内置的。不同版本 spark 内置的 hive 版本也有差异,spark3.4.1 内置 hive2.3.9,spark3.0.3 内置 hive2.3.7。在 spark-shell 中使用 spark.sql 时应该用的是内置的,因为那会没有 Java jar 包,启动也仅仅是在命令行敲了“spark-shell”。

(2)当场下载。配置spark.sql.hive.metastore.version=2.1.1 spark.sql.hive.metastore.jars=maven ,当执行spark.sql 时会先从 maven 仓库下载 2.1.1 相关的依赖到本地 /root/.livy/jars 路径下,大概 188 个 jar 包,总大小 200M 左右。但这种方式当网速很慢或者 maven 仓库没有某些依赖时会下载失败,而且当场下载也不适合生产环境。

(3)指定版本以及依赖的路径。

  • spark 3.1.0 之前配置 spark.sql.hive.metastore.version=2.1.1 spark.sql.hive.metastore.jars=/path-to-hive-jars/* 。执行 spark.sql 时就会率先从 path-to-hive-jars 路径下寻找依赖。
  • spark 3.1.0 之后需要配置 spark.sql.hive.metastore.version=2.1.1 spark.sql.hive.metastore.jars=pathspark.sql.hive.metastore.jars.path=path-to-hive-jars。“path-to-hive-jars” 可以是 HDFS 上的路径,具体细节看表格介绍。

​ 这种方式可以用在生产环境中。

如果采用方式(3)怎么提前获取到正确的依赖,既能跟 spark 兼容又能和集群 hive 通信没问题?

要操作哪个集群如果该集群 hive 在 spark 版本兼容的范围内。直接将集群 hive/lib 下的全部 jar 包(200M左右)“怼” 给 spark 就可以了。(可能用不了那么多,但筛选需要做实验测试)。

下面是在 CDH 集群执行导入操作时的 spark-submit 命令。提前将 CDH 的 hive/lib 下的 jar 包拿出来挂载到容器的 /opt/ml/input/data/training/sparkjar/hive-jars 路径下。

#  在 k8s 容器中执行
/usr/local/spark/bin/spark-submit \
--conf spark.driver.bindAddress=172.16.0.44 \
--deploy-mode client \
--conf spark.sql.hive.metastore.jars=/data/training/sparkjar/hive-jars/* \
--conf spark.sql.hive.metastore.version=2.1.1 \
--properties-file /opt/spark/conf/spark.properties \
--class com.spark.SparkHiveApplication \
local:///data/training/sparkjar/hive-metastore-spark-app-jar-with-dependencies.jar \
WriteSql=TE9BRCBEQVRBIExPQ0FMIElOUEFUSCAnL29wdC9tbC9vdXRwdXQvMTc1NjQ2NDY2MDY3Mzk4NjU3LzE3NTY0NjQ2NjA2NzM5ODY1Ny9wYXJ0LTAwMDAwLWVhYjA2ZWZiLTcwNTktNGI4MS04YmRhLWE3NGE5Yzg3OTY2MS1jMDAwLmNzdicgSU5UTyBUQUJMRSBkdF90aW9uZV90ZXN0XzIwMjIwNzIyIHBhcnRpdGlvbiAocGFydF9udW09JzEnKQ==

与工程结合时肯定能获取到全部 jar 包以及找到合适的“怼”方式。这里列举的只是一种向 spark 任务添加依赖的方式。

尝试打“瘦”包

在创建 assembly jar 的时候,将 spark-hive_2.1 的生命周期设置为 provided,即不将该依赖打入最后的 jar 包。因为在运行 jar 任务时集群管理器可以自己提供依赖的 jar。而且 spark-hive 在 maven 官网的生命周期就被给定是 provided。

没有 spark-hive 依赖的 jar 包大小 9M (之前是 144M),分别在 CDP 和 CDH 上执行导入导出操作。结果:

  • CDP 集群测试通过。

  • CDH 集群异常。猜测是原生 spark3 和 hive-metastore:2.1.1-cdh6.3.3 不兼容(发行版有时会在原生基础上做改动),改用方式(3)中的配置后导入导出功能正常。

如果集群采用发行版部署,大版本下各组件兼容的可能性更大些。而且当频繁调试 Java jar 功能时 9M 大小缩短了上传时间,效率也变高了。

小结

通过配置的方式可以指定 spark 使用的 hiveMetastore。优先使用集群自带的依赖可以在一定程度上减少组件不兼容异常。Java jar 包中只管应用程序怎么写,依赖让集群提供,可以解除 jar 包与某个大数据集群的强绑定关系。但外部配置只是一种解决方案,如果要与工程结合还需要根据场景需求进一步设计实现方案并做实验。文章来源地址https://www.toymoban.com/news/detail-655587.html

到了这里,关于解决执行 spark.sql 时版本不兼容的一种方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • htb monitored root方式其中的一种(仅作记录)

    快下班时候审出来的,目前root的第5种方式 其中 会重启nagios服务,看下manage_services.sh 能看到会是识别完系统做对应的服务操作,其实等同于是一个systemctl 有趣的是 $BASEDIR/manage_services.sh restart nagios 会重启nagios服务 systemctl status nagios能看到服务的位置 这个是有权限修改的 所以

    2024年01月18日
    浏览(39)
  • Java 客户端调用 WebService 接口的一种方式

      通过SoapUI创建一个SOAP Project;   项目名称自定义,WSDL地址维护WebService接口地址。点击OK即可   项目创建完成后,展开WebService项,可以看到具体的接口,打开接口下的Request,右侧面板Form标签下可以清晰的看到请求入参,点击Submit请求按钮可以看到Overview标签下的响应结

    2024年01月18日
    浏览(50)
  • 【Android】RecyclerView实现列表中的Item之间设置间距的一种方式

    RecyclerView 的 Item 默认没有间距是因为 RecyclerView 是一个高度自定义的控件,它的目标是提供一个高效灵活的列表展示,并且适应各种不同的布局需求。 为了让开发者能够充分自定义列表项的布局和样式,RecyclerView 没有默认设置项来添加 item 之间的间距。这样设计的好处是,

    2024年02月13日
    浏览(53)
  • 【LabVIEW学习】5.数据通信之TCP协议,控制电脑的一种方式

    一。tcp连接以及写数据(登录)          数据通信--》协议--》TCP 注意: 事件结构要写延迟!!! 1.tcp连接         创建while循环,中间加入事件结构,创建tcp连接,写入IP地址与端口号 2.写入tcp数据         登录服务器除了要知道IP地址以及端口以外,需要用户名与密

    2024年02月04日
    浏览(41)
  • vscode打开c_cpp_properties.json文件的一种方式

    点击win32 点击json 自动生成了

    2024年01月19日
    浏览(32)
  • Linux下获取另外一个程序的标准输出和标准错误输出的一种实现方式

    问题:一个程序如何获取另外一个程序的标准输出和标准错误输出? 标准输入,标准输出,标准错误输出是一个程序的基本组成,在Linux下一个程序调用另外一个程序,如何获取其标准输出和错误输出呢? 分析:一个程序获取另外一个程序的信息,本质上是IPC(基于进程的通

    2024年02月13日
    浏览(42)
  • <Python>PyQt5中UI界面和逻辑函数分开写的一种方式

    前言 如果经常使用PyQt5这种模块来编写带UI界面的程序,那么很自然的就会涉及到,一旦程序比较大,UI控件多的时候,需要将UI和逻辑程序分离,这样方便管理,也方便维护。 配置: 平台:windows 工具:visual studio code 语言:python 库:PyQt5 本文将提供一个简单但可用的实例,

    2024年02月02日
    浏览(54)
  • 云计算、大数据技术的智慧工地,实现对建筑工地实时监测、管理和控制的一种新型建筑管理方式

    智慧工地是利用物联网、云计算、大数据等技术,实现对建筑工地实时监测、管理和控制的一种新型建筑管理方式。 智慧工地架构: 1、终端层: 充分利用物联网技术、移动应用、智能硬件设备提高现场管控能力。通过RFID、传感器、摄像头、手机等终端设备,实现对项目建

    2024年02月04日
    浏览(45)
  • 【运维】解决 mac office 中乱码的一种方法

    由于微软 office 在 mac 中的代码不匹配等问题,造成部分在 windows 中生成的文档用 mac office 中打开时会有部分乱码。现在笔者找到一种方法,可以解决该问题。 1.安装最新版本的 mac office,我这里是 office2021 2.对windows 中生成有乱码的文档,使用 keynote或者pages 打开,乱码消失

    2024年02月05日
    浏览(40)
  • 安全审计——等级保护日志审计要求的一种解决方案

        在网络安全等级保护中,对日志有着一系列的要求,通常以部署日志审计系统来满足等保的要求,此处我们选择syslog来实现日志的集中收集,统一管理。     在这里我们主要目标是满足安全区域边界、安全管理中心里的下面两条的要求。其中安全管理中心的日志

    2024年02月16日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包