分享

hive中UDF是什么?如何构建和使用UDF

pig2 2014-4-11 01:33:58 发表于 问题解答 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 3 25527
本帖最后由 pig2 于 2014-4-11 01:44 编辑
1.hive中UDF是什么?
2.如何构建UDF?
3.如何实现UDF?
4.如何使用UDF?





已有(3)人评论

跳转到指定楼层
pig2 发表于 2014-4-11 01:43:12


Hive是一种构建在Hadoop上的数据仓库,Hive把SQL查询转换为一系列在Hadoop集群中运行的MapReduce作业,是MapReduce更高层次的抽象,不用编写具体的MapReduce方法。Hive将数据组织为表,这就使得HDFS上的数据有了结构,元数据即表的模式,都存储在名为metastore的数据库中。

1.UDF是什么?

hive的类SQL预发给数据挖掘工作者带来了很多便利,海量数据通过简单的sql就可以完成分析,有时候hive提供的函数功能满足不了业务需要,就需要我们自己来写UDF函数来辅助完成,下面用一个简单的例子说明过程,以及注意事项。

UDF函数其实就是一个简单的函数,执行过程就是在Hive转换成mapreduce程序后,执行java方法,类似于像Mapreduce执行过程中加入一个插件,方便扩展. UDF只能实现一进一出的操作,如果需要实现多进一出,则需要实现UDAF .

Hive可以允许用户编写自己定义的函数UDF,来在查询中使用。

2.UDF类型


Hive中有3种UDF:
UDF:操作单个数据行,产生单个数据行;
UDAF:操作多个数据行,产生一个数据行。
UDTF:操作一个数据行,产生多个数据行一个表作为输出。

3.如何构建UDF

用户构建的UDF使用过程如下:
第一步:继承UDF或者UDAF或者UDTF,实现特定的方法。
第二步:将写好的类打包为jar。如hivefirst.jar.
第三步:进入到Hive外壳环境中,利用add jar /home/hadoop/hivefirst.jar.注册该jar文件
第四步:为该类起一个别名,create temporary function mylength as 'com.whut.StringLength';这里注意UDF只是为这个Hive会话临时定义的。
第五步:在select中使用mylength();


4.自定义UDF



  1. package whut;
  2. import org.apache.commons.lang.StringUtils;
  3. import org.apache.hadoop.hive.ql.exec.UDF;
  4. import org.apache.hadoop.io.Text;
  5. //UDF是作用于单个数据行,产生一个数据行
  6. //用户必须要继承UDF,且必须至少实现一个evalute方法,该方法并不在UDF中
  7. //但是Hive会检查用户的UDF是否拥有一个evalute方法
  8. public class Strip extends UDF{
  9.     private Text result=new Text();
  10.     //自定义方法
  11.     public Text evaluate(Text str)
  12.     {
  13.       if(str==null)
  14.         return null;
  15.         result.set(StringUtils.strip(str.toString()));
  16.         return result;
  17.     }
  18.     public Text evaluate(Text str,String stripChars)
  19.     {
  20.         if(str==null)
  21.             return null;
  22.         result.set(StringUtils.strip(str.toString(),stripChars));
  23.         return result;
  24.     }
  25. }
复制代码


注意事项:
   1,一个用户UDF必须继承org.apache.hadoop.hive.ql.exec.UDF;
   2,一个UDF必须要包含有evaluate()方法,但是该方法并不存在于UDF中。evaluate的参数个数以及类型都是用户自己定义的。在使用的时候,Hive会调用UDF的evaluate()方法。




5.该UDAF主要是找到最大值


  1. package whut;
  2. import org.apache.hadoop.hive.ql.exec.UDAF;
  3. import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
  4. import org.apache.hadoop.io.IntWritable;
  5. //UDAF是输入多个数据行,产生一个数据行
  6. //用户自定义的UDAF必须是继承了UDAF,且内部包含多个实现了exec的静态类
  7. public class MaxiNumber extends UDAF{
  8.     public static class MaxiNumberIntUDAFEvaluator implements UDAFEvaluator{
  9.         //最终结果
  10.         private IntWritable result;
  11.         //负责初始化计算函数并设置它的内部状态,result是存放最终结果的
  12.         @Override
  13.         public void init() {
  14.             result=null;
  15.         }
  16.         //每次对一个新值进行聚集计算都会调用iterate方法
  17.         public boolean iterate(IntWritable value)
  18.         {
  19.             if(value==null)
  20.                 return false;
  21.             if(result==null)
  22.               result=new IntWritable(value.get());
  23.             else
  24.               result.set(Math.max(result.get(), value.get()));
  25.             return true;
  26.         }
  27.                                                                                                                                  
  28.         //Hive需要部分聚集结果的时候会调用该方法
  29.         //会返回一个封装了聚集计算当前状态的对象
  30.         public IntWritable terminatePartial()
  31.         {
  32.             return result;
  33.         }
  34.         //合并两个部分聚集值会调用这个方法
  35.         public boolean merge(IntWritable other)
  36.         {
  37.             return iterate(other);
  38.         }
  39.         //Hive需要最终聚集结果时候会调用该方法
  40.         public IntWritable terminate()
  41.         {
  42.             return result;
  43.         }
  44.     }
  45. }
复制代码

注意事项:
1.用户的UDAF必须继承了org.apache.hadoop.hive.ql.exec.UDAF;
2.用户的UDAF必须包含至少一个实现了org.apache.hadoop.hive.ql.exec的静态类,诸如常见的实现了 UDAFEvaluator。
3.一个计算函数必须实现的5个方法的具体含义如下:

  • init():主要是负责初始化计算函数并且重设其内部状态,一般就是重设其内部字段。一般在静态类中定义一个内部字段来存放最终的结果。
  • iterate():每一次对一个新值进行聚集计算时候都会调用该方法,计算函数会根据聚集计算结果更新内部状态。当输入值合法或者正确计算了,则就返回true。
  • terminatePartial():Hive需要部分聚集结果的时候会调用该方法,必须要返回一个封装了聚集计算当前状态的对象。
  • merge():Hive进行合并一个部分聚集和另一个部分聚集的时候会调用该方法。
  • terminate():Hive最终聚集结果的时候就会调用该方法。计算函数需要把状态作为一个值返回给用户。


4.部分聚集结果的数据类型和最终结果的数据类型可以不同。









回复

使用道具 举报

june_fu 发表于 2015-3-8 20:49:35
UDTF呢?是不是好友后续的?
写的很好的例子,谢谢。
回复

使用道具 举报

刚果 发表于 2015-9-1 16:51:32
来个UDTF例子吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条