Spark二次调用Hive UDF异常问题解决办法

您所在的位置:网站首页 hive调用spark Spark二次调用Hive UDF异常问题解决办法

Spark二次调用Hive UDF异常问题解决办法

2023-08-22 15:51| 来源: 网络整理| 查看: 265

异常如下:

No handler for UDF/UDAF/UDTF 'com.******.***': java.lang.ClassNotFoundException: com.***; line 1 pos 7 org.apache.spark.sql.AnalysisException: No handler for UDF/UDAF/UDTF 'com.***': java.lang.ClassNotFoundException: com.***; line 1 pos 7

这个异常其实是Spark sql在对hive 自定义udf 二次调用导致的异常的BUG,现在还没修复,受影响的Spark版本包括spark2.3/2.4 详情见这个issue   自定义udf 二次调用导致的异常

我尝试发现是在启动spark 带上 --jars指定udf jar包就不会出现该问题。不带jar包 第一次调用executor会从远程下载这个jar 正常执行没出问题,第二次classloader加载时会出问题,具体原因不明,后面再研究。

 

再总结下Spark UDF与Hive UDF那些小坑:

1.首先 Spak UDF不支持重载,Hive UDF 可以重载。Spark SQL某些内部函数是有重载功能的,比如to_timestamp() 这些是通过FunctionRegistry这个类注册的

如果你可以改源码 那还是有办法重载的~。但是外部的自定义的Spark udf是无法实现重载的,因为是外部是通过UDFRegistration这个类注册的,且如果你写了个两个同名的spark udf,只会被后者覆盖。那有没有方法重载呢?当然是有了,集成hive呗,不过是曲线救国~所以也带来了上面说的bug。

2.Spark虽然可以集成Hive,使用hive内置的函数。 hive使用自定义的UDF也很简单,写完udf jar包后在hive窗口下 执行相应的udf创建语句create temporary function *** as 'com.*********';就好了,同样,这段创建语句也可以在Spark SQL里执行,Spark会通过内置的HiveClient创建这个udf 但是问题来了,如果我Spark udf里已经有这个函数了,又通过spark sql去创建这个同名的udf,不好意思,会报错~。

3.那我不通过spark去创建这个udf A,我在hive窗口创建好这个udf A,在Spark 中我也注册个udf A,然后spark也集成了hive,我现在sql执行这个udf A,用的是Spark的udf呢还是Hive的udf呢?当然是Spark的udf了~。原因很简单,集成Hive后,Spark会调用 Hive 的 Registry 接口,把Hive内置的udf函数和class都注册到 system Registry中,查找Function时,先获取当前session中注册的temporary function,再取system中注册的function。

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3