Hive开发UDF

阅读: 评论:0

Hive开发UDF

Hive开发UDF

Hive开发UDF

从无到有开发hive的udf,本篇不针对简单的,针对复杂参数



 移除点击此处添加图片说明文字

目录:

add jar /opt/workspace/udf/GetAppUDF.jar;

移除点击此处添加图片说明文字



小坑,路径一定要写对,之前出现文件找不到,我以为要放到hdfs上面呢。

[hive@dw-gateway03 root]$ hadoop fs -mkdir /user/hive/warehouse/udf

[hive@dw-gateway03 root]$ hadoop fs -put /opt/workspace/udf​/GetAppUDF-1.0.jar /user/hive/warehouse/udf/GetAppUDF.jar​

后来及时悬崖勒马。



创建临时函数:

create temporary function GetAppUDF as &#st.Hive.udf.GetAppUDF';

移除点击此处添加图片说明文字

​哦,原来是jdk版本有问题啊。

移除点击此处添加图片说明文字

​本机是最新版,看下服务器的,

移除点击此处添加图片说明文字

​嗯,1.7.0_55的,咱们要去安装一下了。

移除点击此处添加图片说明文字

安装

移除点击此处添加图片说明文字

​等一下进度

移除点击此处添加图片说明文字

移除点击此处添加图片说明文字

移除点击此处添加图片说明文字

​然后咱们remove换一下jdk

搞定之后,重新打包吧。

然后发布,还是这个玩意:

移除点击此处添加图片说明文字

​好难受呀。

然后咱们换第三个,1.7.0.88次修改,第三次装jdk好了,报另一个错了。

解决了这个问题了,还是蛮开心的。

移除点击此处添加图片说明文字

​咱们再:

create temporary function GetAppUDF as &#st.Hive.udf.GetAppUDF'; 

create temporary function GetAppUDF  as ' st.Hive.udf.GetAppUDF '; 

总是报错:FAILED: st.Hive.udf.GetAppUDF not found

后来我发现了,乱倒腾发现的。

移除点击此处添加图片说明文字

​那我们把他重新打印一遍:


add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF'; 


然后我们运行

移除点击此处添加图片说明文字

​我靠,然后我desc safedata.apk_use

发现

移除点击此处添加图片说明文字

​array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>

这种格式的字段,我第一次见到。

然后咱们查资料发现这么个东西:

移除点击此处添加图片说明文字

​暂且理解为全部强制性读进来。

但是这回报错:

移除点击此处添加图片说明文字

​这个到底是怎么回事呢?

原来是因为我们复制了很多>

移除点击此处添加图片说明文字

​那好,我们把>删掉,重来。

select  uuid,GetAppUDF(apk_use),pt from safedata.apk_use limit 100;

结果:

FAILED: SemanticException [Error 10014]: Line 3:1 Wrong arguments 'apk_use': No matching method for st.Hive.udf.GetAppUDF with (array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>). Possible choices: _FUNC_(string)  

原因就是这个格式,很恶心, array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>

卡了很久,怎么办呢。

卡住了很久,我感觉要来个狠得。请看

移除点击此处添加图片说明文字

​结果气得想吐学:

移除点击此处添加图片说明文字

​java也这么蠢啊,好难受,妈的。

去网上找大神操作吧。

移除点击此处添加图片说明文字

​还是老样子,卡在这里快一到两个小时了,问了一下老大,他也不知道,让我研究。那好吧,继续研究吧。


我们看一篇文章:

Hive中,除了提供丰富的内置函数(见[一起学Hive]之二–Hive函数大全-完整版)之外,还允许用户使用Java开发自定义的UDF函数。

开发自定义UDF函数有两种方式,一个是继承org.apache.hadoop.UDF,另一个是继承org.apache.hadoop.hive.ic.GenericUDF;

如果是针对简单的数据类型(比如String、Integer等)可以使用UDF,如果是针对复杂的数据类型(比如Array、Map、 Struct等),可以使用GenericUDF,另外,GenericUDF还可以在函数开始之前和结束之后做一些初始化和关闭的处理操作。

UDF

使用UDF非常简单,只需要继承org.apache.hadoop.UDF,并定义

public Object evaluate(Object args) {} 方法即可。

比如,下面的UDF函数实现了对一个String类型的字符串取HashMD5:

  1. package com.lxw1234.hive.udf;
  2. import org.apache.hadoop.hbase.util.Bytes;
  3. import org.apache.hadoop.hbase.util.MD5Hash;
  4. import org.apache.hadoop.UDF;
  5. public class HashMd5 extends UDF {
  6. public String evaluate(String cookie) {
  7. return Bytes(cookie));
  8. }
  9. }

将上面的HashMd5类打成jar包,udf.jar

使用时候,在Hive命令行执行:

  1. add jar file:///tmp/udf.jar;
  2. CREATE temporary function str_md5 as 'com.lxw1234.hive.udf.HashMd5';
  3. select str_md5(‘lxw1234’) from dual;


具体文章我粘贴一下地址:

.html


GenericUDF

继承org.apache.hadoop.hive.ic.GenericUDF之后,需要重写几个重要的方法:

publicvoid configure(MapredContext context) {}

//可选,该方法中可以通过JobConf()获取job执行时候的Configuration;

//可以通过Configuration传递参数值

public ObjectInspector initialize(ObjectInspector[] arguments)

//必选,该方法用于函数初始化操作,并定义函数的返回值类型;

//比如,在该方法中可以初始化对象实例,初始化数据库链接,初始化读取文件等;

public Object evaluate(DeferredObject[] args){}

//必选,函数处理的核心方法,用途和UDF中的evaluate一样;

public String getDisplayString(String[] children)

//必选,显示函数的帮助信息

public void close(){}

//可选,map完成后,执行关闭操作


所以我们新写一个类吧。

移除点击此处添加图片说明文字

​然后我们改写之后,出现:

移除点击此处添加图片说明文字

add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF2'; 

select  uuid,GetAppUDF(apk_use),pt from safedata.apk_use limit 100; 

但是,我们看到还是这个问题啊、

Exception in thread "main" java.lang.NoClassDefFoundError: net/sf/json/JSONArray

那接下来该怎么办,只能重新想办法了。

后来我想到了一个好的点子,卡了一整个下午,我就在向着怎么会找不到json类,一个原因是真的转不了,还有一个可能就是,根本没有接收到参数,所以空,也会报这个错。那么我换个巧妙地方式,你不是要微博的数据吗。那我这样。

移除点击此处添加图片说明文字

​可以,很巧妙,发布试一下:

移除点击此处添加图片说明文字

那我们把object换成String把。重新发布。​

但是:Failed with exception java.io.IOException:org.apache.hadoop.adata.HiveException: java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;

这个其实就是转换错误的,我们看看程序吧。

我靠你大爷的,改了好久好久我的天:

移除点击此处添加图片说明文字

卡了太久了。受不了了。然后我思考了很久,发现了这个代码

移除点击此处添加图片说明文字

​细心的发现了这个是list,我靠,坑啊,血坑。

//StandardListObjectInspector(returnOI);

return returnOI;

移除点击此处添加图片说明文字

​给力了。我的哥。

好了,接下来开发。

add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF2'; 

drop stweiboudf;

create stWeiboUDF as select im,is,uuid,GetAppUDF(apk_list) ifWeibo,dt,pt from safedata.apk_list where apk_list is not null;


移除点击此处添加图片说明文字

​好像有不少任务,

移除点击此处添加图片说明文字

​等到hive转化的mapreduce跑完了,就可以了。

移除点击此处添加图片说明文字

​然后我们发现全量表切割后,字段全部为false。

那简单,我们换一个应用试一试,换唯品会吧,或者是别的什么的。

移除点击此处添加图片说明文字

​如果换成“微博”还不行,要么就是utf-8的事情,要么,就真的没有微博,接下来就换别的试试了,没有办法了。只能如此。等等跑完了看看吧,这个udf有点恶心。

移除点击此处添加图片说明文字

这就很尴尬了,我们换一个。看看到底怎么回事。然后我试了一试别的,发现怎么都是false,这就有问题了。

这个中间报了个这么错:

移除点击此处添加图片说明文字

​因为是那种特殊数组格式,我们得加一个is not null

改好了之后,还是这样,算了,先告一段落吧,下午要开发python爬虫了,没时间搞这个了,先停一段落吧。等这周后期,咱们再整这个吧,现在就差一点点了。后面如果有时间我们再把这个array<struct<>>解析一下吧。

其实简单的udf很好写,就是重写一个 evaluate函数,然后用参数取得字段值,分解,复杂的这个,继承GenericUDF,重写三个方法,initialize、evaluate、getdisplayString

移除点击此处添加图片说明文字

目录:

add jar /opt/workspace/udf/GetAppUDF.jar;

移除点击此处添加图片说明文字



小坑,路径一定要写对,之前出现文件找不到,我以为要放到hdfs上面呢。

[hive@dw-gateway03 root]$ hadoop fs -mkdir /user/hive/warehouse/udf

[hive@dw-gateway03 root]$ hadoop fs -put /opt/workspace/udf​/GetAppUDF-1.0.jar /user/hive/warehouse/udf/GetAppUDF.jar​

后来及时悬崖勒马。



创建临时函数:

create temporary function GetAppUDF as &#st.Hive.udf.GetAppUDF';

移除点击此处添加图片说明文字

​哦,原来是jdk版本有问题啊。

移除点击此处添加图片说明文字

​本机是最新版,看下服务器的,

移除点击此处添加图片说明文字

​嗯,1.7.0_55的,咱们要去安装一下了。

移除点击此处添加图片说明文字

安装

移除点击此处添加图片说明文字

​等一下进度

移除点击此处添加图片说明文字

移除点击此处添加图片说明文字

移除点击此处添加图片说明文字

​然后咱们remove换一下jdk

搞定之后,重新打包吧。

然后发布,还是这个玩意:

移除点击此处添加图片说明文字

​好难受呀。

然后咱们换第三个,1.7.0.88次修改,第三次装jdk好了,报另一个错了。

解决了这个问题了,还是蛮开心的。

移除点击此处添加图片说明文字

​咱们再:

create temporary function GetAppUDF as &#st.Hive.udf.GetAppUDF'; 

create temporary function GetAppUDF  as ' st.Hive.udf.GetAppUDF '; 

总是报错:FAILED: st.Hive.udf.GetAppUDF not found

后来我发现了,乱倒腾发现的。

移除点击此处添加图片说明文字

​那我们把他重新打印一遍:


add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF'; 


然后我们运行

移除点击此处添加图片说明文字

​我靠,然后我desc safedata.apk_use

发现

移除点击此处添加图片说明文字

​array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>

这种格式的字段,我第一次见到。

然后咱们查资料发现这么个东西:

移除点击此处添加图片说明文字

​暂且理解为全部强制性读进来。

但是这回报错:

移除点击此处添加图片说明文字

​这个到底是怎么回事呢?

原来是因为我们复制了很多>

移除点击此处添加图片说明文字

​那好,我们把>删掉,重来。

select  uuid,GetAppUDF(apk_use),pt from safedata.apk_use limit 100;

结果:

FAILED: SemanticException [Error 10014]: Line 3:1 Wrong arguments 'apk_use': No matching method for st.Hive.udf.GetAppUDF with (array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>). Possible choices: _FUNC_(string)  

原因就是这个格式,很恶心, array<struct<apk:string,n:string,v:string,v_n:string,c:int,t:int>>

卡了很久,怎么办呢。

卡住了很久,我感觉要来个狠得。请看

移除点击此处添加图片说明文字

​结果气得想吐学:

移除点击此处添加图片说明文字

​java也这么蠢啊,好难受,妈的。

去网上找大神操作吧。

移除点击此处添加图片说明文字

​还是老样子,卡在这里快一到两个小时了,问了一下老大,他也不知道,让我研究。那好吧,继续研究吧。


我们看一篇文章:

Hive中,除了提供丰富的内置函数(见[一起学Hive]之二–Hive函数大全-完整版)之外,还允许用户使用Java开发自定义的UDF函数。

开发自定义UDF函数有两种方式,一个是继承org.apache.hadoop.UDF,另一个是继承org.apache.hadoop.hive.ic.GenericUDF;

如果是针对简单的数据类型(比如String、Integer等)可以使用UDF,如果是针对复杂的数据类型(比如Array、Map、 Struct等),可以使用GenericUDF,另外,GenericUDF还可以在函数开始之前和结束之后做一些初始化和关闭的处理操作。

UDF

使用UDF非常简单,只需要继承org.apache.hadoop.UDF,并定义

public Object evaluate(Object args) {} 方法即可。

比如,下面的UDF函数实现了对一个String类型的字符串取HashMD5:

  1. package com.lxw1234.hive.udf;
  2. import org.apache.hadoop.hbase.util.Bytes;
  3. import org.apache.hadoop.hbase.util.MD5Hash;
  4. import org.apache.hadoop.UDF;
  5. public class HashMd5 extends UDF {
  6. public String evaluate(String cookie) {
  7. return Bytes(cookie));
  8. }
  9. }

将上面的HashMd5类打成jar包,udf.jar

使用时候,在Hive命令行执行:

  1. add jar file:///tmp/udf.jar;
  2. CREATE temporary function str_md5 as 'com.lxw1234.hive.udf.HashMd5';
  3. select str_md5(‘lxw1234’) from dual;


具体文章我粘贴一下地址:

.html


GenericUDF

继承org.apache.hadoop.hive.ic.GenericUDF之后,需要重写几个重要的方法:

publicvoid configure(MapredContext context) {}

//可选,该方法中可以通过JobConf()获取job执行时候的Configuration;

//可以通过Configuration传递参数值

public ObjectInspector initialize(ObjectInspector[] arguments)

//必选,该方法用于函数初始化操作,并定义函数的返回值类型;

//比如,在该方法中可以初始化对象实例,初始化数据库链接,初始化读取文件等;

public Object evaluate(DeferredObject[] args){}

//必选,函数处理的核心方法,用途和UDF中的evaluate一样;

public String getDisplayString(String[] children)

//必选,显示函数的帮助信息

public void close(){}

//可选,map完成后,执行关闭操作


所以我们新写一个类吧。

移除点击此处添加图片说明文字

​然后我们改写之后,出现:

移除点击此处添加图片说明文字

add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF2'; 

select  uuid,GetAppUDF(apk_use),pt from safedata.apk_use limit 100; 

但是,我们看到还是这个问题啊、

Exception in thread "main" java.lang.NoClassDefFoundError: net/sf/json/JSONArray

那接下来该怎么办,只能重新想办法了。

后来我想到了一个好的点子,卡了一整个下午,我就在向着怎么会找不到json类,一个原因是真的转不了,还有一个可能就是,根本没有接收到参数,所以空,也会报这个错。那么我换个巧妙地方式,你不是要微博的数据吗。那我这样。

移除点击此处添加图片说明文字

​可以,很巧妙,发布试一下:

移除点击此处添加图片说明文字

那我们把object换成String把。重新发布。​

但是:Failed with exception java.io.IOException:org.apache.hadoop.adata.HiveException: java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;

这个其实就是转换错误的,我们看看程序吧。

我靠你大爷的,改了好久好久我的天:

移除点击此处添加图片说明文字

卡了太久了。受不了了。然后我思考了很久,发现了这个代码

移除点击此处添加图片说明文字

​细心的发现了这个是list,我靠,坑啊,血坑。

//StandardListObjectInspector(returnOI);

return returnOI;

移除点击此处添加图片说明文字

​给力了。我的哥。

好了,接下来开发。

add jar /opt/workspace/udf/GetAppUDF.jar;

create temporary function GetAppUDF  as &#st.Hive.udf.GetAppUDF2'; 

drop stweiboudf;

create stWeiboUDF as select im,is,uuid,GetAppUDF(apk_list) ifWeibo,dt,pt from safedata.apk_list where apk_list is not null;


移除点击此处添加图片说明文字

​好像有不少任务,

移除点击此处添加图片说明文字

​等到hive转化的mapreduce跑完了,就可以了。

移除点击此处添加图片说明文字

​然后我们发现全量表切割后,字段全部为false。

那简单,我们换一个应用试一试,换唯品会吧,或者是别的什么的。

移除点击此处添加图片说明文字

​如果换成“微博”还不行,要么就是utf-8的事情,要么,就真的没有微博,接下来就换别的试试了,没有办法了。只能如此。等等跑完了看看吧,这个udf有点恶心。

移除点击此处添加图片说明文字

这就很尴尬了,我们换一个。看看到底怎么回事。然后我试了一试别的,发现怎么都是false,这就有问题了。

这个中间报了个这么错:

移除点击此处添加图片说明文字

​因为是那种特殊数组格式,我们得加一个is not null

改好了之后,还是这样,算了,先告一段落吧,下午要开发python爬虫了,没时间搞这个了,先停一段落吧。等这周后期,咱们再整这个吧,现在就差一点点了。后面如果有时间我们再把这个array<struct<>>解析一下吧。

其实简单的udf很好写,就是重写一个 evaluate函数,然后用参数取得字段值,分解,复杂的这个,继承GenericUDF,重写三个方法,initialize、evaluate、getdisplayString













本文发布于:2024-02-01 05:35:06,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170673690834267.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Hive   UDF
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23