Hive自定义函数(generic)

来源:互联网 发布:网络婚恋诈骗广东 编辑:程序博客网 时间:2024/06/05 15:01

Hive自定义generic(通用)函数,性能比simple性能高,同时能处理simple不能处理的问题,如:simple不能处理Hive的struct结构。

 

hive generic 函数详细见hive 目录:

Text代码  收藏代码
  1. src\ql\src\java\org\apache\hadoop\hive\ql\udf\generic  

 

 

一、GenericUDF

1.UDF首先将输入数据转化为对应的ObjectInspectors对象

 

2.Hive自带的很多函数都是使用GenericUDF,例如:concat_ws, case when等等

 

3.UDF输入是单行数据,产生一个数据输出。

 

编写GenericUDF步骤:

 

1.继承GenericUDF类,实现以下3个方法:

 

Java代码  收藏代码
  1. public ObjectInspector initialize(ObjectInspector[] arguments)  
  2. public Object evaluate(DeferredObject[] arguments)  
  3. public String getDisplayString(String[] children)  

 

2.initialize方法在SQL调用UDF函数中,首先被调用,它完成下面4件事:

(1)验证输入的类型是否预期输入

(2)设置返回值,设置返回一个与预期输出类型相符的ObjectInspector ,假设需要返回的是一个string类型,由于string类型对应的分布式类型是TextWritable,所以在initialize返回的类型是

 

Java代码  收藏代码
  1. return PrimitiveObjectInspectorFactory.writableStringObjectInspector;  

 (3)存储在全局变量的ObjectInspectors元素的输入

 

 (4)设置存储变量的输出

其中第三步不是必须的,因为全局变量能在evaluate方法中以局部变量的形式声明并处理,但是在initialize存储全局变量,只需要初始化一次。

 

3.evaluate方法:处理函数从输入到输出的逻辑,返回函数处理预期结果的值

 

(1)第一步:将输入值,声明局部变量通过initialize方法判断合法的变量存储。

(2)第二步:处理函数逻辑,将输入通过代码逻辑得到结果并返回。

其中,Hive中的变量类型与Java中的变量类型的匹配:

hive类型java类型array<>ArrayList<>struct<>Object

其他类似于hadoop的变量类型,如:string对应hadoop 的TextWritable等等。

 

4.getDisplayString方法

(1)用于explain sql的时候,方便查看其返回的格式

(2)类似于java的toString方法

 

案例分析:

 

该案例实现,输入一个用户编号user_id,一个游戏列表game_list,输出是用户与随机游戏列表中的一款游戏,以逗号分隔:user_id,game,在hive外层使用split函数将其划分,得到用户随机的一款游戏。

源码分析:

 

Java代码  收藏代码
  1. import java.util.List;  
  2.   
  3. import org.apache.hadoop.hive.ql.exec.UDFArgumentException;  
  4. import org.apache.hadoop.hive.ql.metadata.HiveException;  
  5. import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;  
  6. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;  
  7. import org.apache.hadoop.hive.serde2.objectinspector.StandardListObjectInspector;  
  8. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;  
  9. import org.apache.hadoop.io.Text;  
  10.   
  11. /** 
  12.  * 随机用户匹配游戏列表中的一款游戏 
  13.  *  
  14.  * @author huzhirong 
  15.  *  
  16.  */  
  17. public class UDFRandomUidGame extends GenericUDF {  
  18.   
  19.         //声明全局输入变量  
  20.     StandardListObjectInspector dimGameListOI;  
  21.     ObjectInspector uidOI;  
  22.         //声明输出变量  
  23.     private final Text text = new Text();  
  24.       
  25.         //处理业务逻辑  
  26.     @Override  
  27.     public Object evaluate(DeferredObject[] vals) throws HiveException {  
  28.         text.clear();  
  29.         Text uid = (Text) vals[0].get();  
  30.         Text seq = new Text(",");  
  31.         @SuppressWarnings("unchecked")  
  32.         List<Text> list = (List<Text>) dimGameListOI.getList(vals[1].get());  
  33.         Text game = list.get((int) (Math.random() * list.size()));  
  34.         text.append(game.getBytes(), 0, game.getLength());  
  35.         text.append(seq.getBytes(), 0, seq.getLength());  
  36.         text.append(uid.getBytes(), 0, uid.getLength());  
  37.         return text;  
  38.     }  
  39.   
  40.         //类似于java的toString方法,hive中在使用explain的时候调用该方法  
  41.     @Override  
  42.     public String getDisplayString(String[] args) {  
  43.         StringBuilder sb = new StringBuilder();  
  44.         if (args != null && args.length > 0) {  
  45.             for (String arg : args) {  
  46.                 sb.append(arg).append(',');  
  47.             }  
  48.         }  
  49.         if (sb.length() > 0) {  
  50.             sb.setCharAt(sb.length() - 1')');  
  51.         } else {  
  52.             sb.append(')');  
  53.         }  
  54.         sb.insert(0"random_list_element(");  
  55.   
  56.         return sb.toString();  
  57.     }  
  58.   
  59.     @Override  
  60.     public ObjectInspector initialize(ObjectInspector[] ois)  throws UDFArgumentException {  
  61.         uidOI = (ObjectInspector)ois[0];  
  62.         dimGameListOI = (StandardListObjectInspector)ois[1];  
  63.                 //返回值类型  
  64.         return PrimitiveObjectInspectorFactory.writableStringObjectInspector;  
  65.     }  
  66.   
  67. }  
原创粉丝点击