Hive上使用UDF遇到的诡异的事

Hive上使用UDF遇到的诡异的事

这里记录一下自己用UDF遇到的问题,最后虽然解决了也知道是什么原因导致的,但是没有从代码或Hive层面去理解,全是靠自己意会出来的。

背景

一个业务需求,需要在hive上操作,逻辑比较复杂,写了两个udf,用的是一项目,对应的目录如下:

└─src
    ├─main
       └─java
            └─com
              └─quick
                └─udf
                  └─fun1
                  └─fun2

大致简化了一下,这样的话两个udf的class就是

fun1 ---> com.quick.udf.fun1
fun1 ---> com.quick.udf.fun2

打包后的jar为fun_v1.0.jar
最终的用法如下

DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v1.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';

select fun1(1,2,3) from tablea;


DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;
DROP TEMPORARY FUNCTION fun2;
ADD jar hdfs:///tmp/udf/fun_v1.0.jar;
CREATE TEMPORARY FUNCTION fun2 'com.quick.udf.fun2';

select fun2(1,2,3) from table b


select fun1(a,b,c) from tablec

我们公司有自己的Hive平台, udf函数申请的时候一定要一个函数名对应一个jar包和class路径,所以上面两个udf就申请了两次,使用的时候就要add两次。
这个上线后没有任何问题,最近有了新的需求,要对fun1进行调整,改动还比较大,最后的jar包版本为v2.0,用法如下

DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v2.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';

select fun1(1,2,3,4,5) from tablea;


DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;
DROP TEMPORARY FUNCTION fun2;
ADD jar hdfs:///tmp/udf/fun_v1.0.jar;
CREATE TEMPORARY FUNCTION fun2 'com.quick.udf.fun2';

select fun2(1,2,3) from table b



select fun1(a,b,c,d,e) from tablec

这里就用了两个jar包,虽然这两个中的fun2代码是一样的,看起来没问题,理论上来说也是没问题!

噩梦开始

开始测试执行的时候,就开始报错,报的错非常的奇怪
第一次报错

Exception in thread "main" org.apache.hive.com.esotericsoftware.kryo.KryoException: java.lang.UnsupportedOperationException

(具体的日志没有保存)
所有的焦点都被KryoException带走, 说是序列化的问题,然后就对自己的udf进行各种测试,发现并不会出现这个问题(期间也测出了一个小bug,业务上的)
当时找了自己测了半天,又找了半天问题,最终在这里找到了“解决方案”
https://issues.apache.org/jira/browse/HIVE-7711

然后就写了个DoNothingSerializer,再在fun1的类上添加@DefaultSerializer(value = DoNothingSerializer.class)的注解,由于已经到了晚上(晚上十点)方法没有被审核,就早早的睡觉了。

第二天赶紧催了下同事审核,审核过之后,满怀信心的去执行,发现还是不行,当场崩溃!
第二次报错
这次报错跟之前不一样,至少跟udf相关的出来了,如下

Serialization trace:
typeInfo (org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc)
colExprMap (org.apache.hadoop.hive.ql.exec.SelectOperator)
childOperators (org.apache.hadoop.hive.ql.exec.JoinOperator)
reducer (org.apache.hadoop.hive.ql.plan.ReduceWork)
org.apache.hive.com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: Illegal character in path at index 0: ��verifyPackType���h
Serialization trace:
typeInfo (org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc)
colExprMap (org.apache.hadoop.hive.ql.exec.SelectOperator)
childOperators (org.apache.hadoop.hive.ql.exec.JoinOperator)
reducer (org.apache.hadoop.hive.ql.plan.ReduceWork)

里面有个verifyPackType, 看到这个时候,心里一阵窃喜,因为这说明是跟udf有关的错,不是自己sql的问题,然后拿着这个单词去项目里搜,搜来搜去都没有,很郁闷,怎么会这样!突然,我想到这是不是上一个版本的问题,是不是我的udf的引入不对,于是我做了如下两次尝试:
第一次尝试:

DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v2.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';

select fun1(1,2,3,4,5) from tablea;


DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;
DROP TEMPORARY FUNCTION fun2;
ADD jar hdfs:///tmp/udf/fun_v1.0.jar;
CREATE TEMPORARY FUNCTION fun2 'com.quick.udf.fun2';

select fun2(1,2,3) from table b
DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v2.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';
select fun1(a,b,c,d,e) from tablec

我把它们拆成了两次去执行,注意是两个窗口,结果是正常执行,没有报错!!!看来是udf用的有问题
第二次尝试,每次用完udf就及时的drop掉

DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v2.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';

select fun1(1,2,3,4,5)

DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;
DROP TEMPORARY FUNCTION fun2;
ADD jar hdfs:///tmp/udf/fun_v1.0.jar;
CREATE TEMPORARY FUNCTION fun2 'com.quick.udf.fun2';

select fun2(1,2,3) from table b
DROP TEMPORARY FUNCTION fun2;
DELETE jar hdfs:///tmp/udf/fun_v1.0.jar;


DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;
DROP TEMPORARY FUNCTION fun1;
ADD jar hdfs:///tmp/udf/fun_v2.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';
select fun1(a,b,c,d,e) from tablec
DROP TEMPORARY FUNCTION fun1;
DELETE jar hdfs:///tmp/udf/fun_v2.0.jar;

然后放在一个脚本里一起执行,竟然成功了!!!
当时感觉整个天都亮了,世界如此的美好!!!

冷静下来后,就准备了测试的脚本,每天都来跑一下,关注一下运行的情况,这样第二天就过去了!

第三天,早上慢悠悠的打开电脑,把测试脚本跑了起来,自己喝着茶慢慢的看结果,还哼着歌。。。结果又报错了!!!心里咯噔一下。。。报错如下:

image-20200708105118033.png

提示resultmap的问题,突然醒悟过来,难道两个udf在使用的时候“错位”了?这样只能该项目了,时间紧迫,花了十分钟将目录结构改造如下

module1
└─src
    ├─main
       └─java
            └─com
              └─quick
                └─udf
                  └─fun1
module2                   
└─src
    ├─main
       └─java
            └─com
              └─quick
                └─seudf
                  └─fun2

这样保证了两个udf不在同一个包下,也保证了一个jar只对应一个udf

最后重新打包

fun1_v3.0.jarfun2_v3.0.jar

对应class为

com.quick.udf.fun1com.quick.seudf.fun1

然后赶紧提交审核,最终的sql如下

DROP TEMPORARY FUNCTION fun1;
DELETE jar hdfs:///tmp/udf/fun1_v3.0.jar;
ADD jar hdfs:///tmp/udf/fun1_v3.0.jar;
CREATE TEMPORARY FUNCTION fun1 'com.quick.udf.fun1';

select fun1(1,2,3,4,5)

DROP TEMPORARY FUNCTION fun2;
DELETE jar hdfs:///tmp/udf/fun2_v3.0.jar;
ADD jar hdfs:///tmp/udf/fun2_v3.0.jar;
CREATE TEMPORARY FUNCTION fun2 'com.quick.seudf.fun2';

select fun2(1,2,3) from table b


select fun1(a,b,c,d,e) from tablec

然后执行,没有报错,后续我每天都会去执行,大约持续了一周,都没有报错,到此,问题得到解决!!!

后续

自己不是做hive开发的,也是第一次写udf,遇到这些稀奇古怪,真的是无助。。。。但是始终相信那句话

大胆假设小心求证

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269