1. 程式人生 > >hive中UDF、UDAF和UDTF使用

hive中UDF、UDAF和UDTF使用

Hive進行UDF開發十分簡單,此處所說UDF為Temporary的function,所以需要hive版本在0.4.0以上才可以。

一、背景:Hive是基於Hadoop中的MapReduce,提供HQL查詢的資料倉庫。Hive是一個很開放的系統,很多內容都支援使用者定製,包括:

a)檔案格式:Text File,Sequence File
b)記憶體中的資料格式: Java Integer/String, Hadoop IntWritable/Text
c)使用者提供的 map/reduce 指令碼:不管什麼語言,利用 stdin/stdout 傳輸資料
d)使用者自定義函式: Substr, Trim, 1 – 1
e)使用者自定義聚合函式: Sum, Average…… n – 1

2、定義:UDF(User-Defined-Function),使用者自定義函式對資料進行處理。

二、用法



1、UDF函式可以直接應用於select語句,對查詢結構做格式化處理後,再輸出內容。
2、編寫UDF函式的時候需要注意一下幾點:
a)自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。
b)需要實現evaluate函。
c)evaluate函式支援過載。

3、以下是兩個數求和函式的UDF。evaluate函式代表兩個整型資料相加,兩個浮點型資料相加,可變長資料相加

Hive的UDF開發只需要重構UDF類的evaluate函式即可。例:

package hive.connect;

import org.apache.hadoop.hive.ql.exec.UDF;

public final class Add extends UDF {
public Integer evaluate(Integer a, Integer b) {
               if (null == a || null == b) {
                               return null;
               } return a + b;
}

public Double evaluate(Double a, Double b) {
               if (a == null || b == null)
                               return null;
                               return a + b;
               }

public Integer evaluate(Integer... a) {
               int total = 0;
               for (int i = 0; i < a.length; i++)
                               if (a[i] != null)
                                             total += a[i];
                                              return total;
                               }
}


4、步驟

a)把程式打包放到目標機器上去;

b)進入hive客戶端,新增jar包:hive>add jar /run/jar/udf_test.jar;

c)建立臨時函式:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';

d)查詢HQL語句:

SELECT add_example(8, 9) FROM scores;

SELECT add_example(scores.math, scores.art) FROM scores;

SELECT add_example(6, 7, 8, 6.8) FROM scores;

e)銷燬臨時函式:hive> DROP TEMPORARY FUNCTION add_example;

5、細節在使用UDF的時候,會自動進行型別轉換,例如:

SELECT add_example(8,9.1) FROM scores;

注:

1. UDF只能實現一進一出的操作,如果需要實現多進一出,則需要實現UDAF

下面來看下UDAF:

(二)、UDAF


1、Hive查詢資料時,有些聚類函式在HQL沒有自帶,需要使用者自定義實現。

2、使用者自定義聚合函式: Sum, Average…… n – 1

UDAF(User- Defined Aggregation Funcation)

一、用法

1、一下兩個包是必須的import org.apache.hadoop.hive.ql.exec.UDAF和 org.apache.hadoop.hive.ql.exec.UDAFEvaluator。

2、函式類需要繼承UDAF類,內部類Evaluator實UDAFEvaluator介面。

3、Evaluator需要實現 init、iterate、terminatePartial、merge、terminate這幾個函式。

a)init函式實現介面UDAFEvaluator的init函式。

b)iterate接收傳入的引數,並進行內部的輪轉。其返回型別為boolean。

c)terminatePartial無引數,其為iterate函式輪轉結束後,返回輪轉資料,terminatePartial類似於hadoop的Combiner。

d)merge接收terminatePartial的返回結果,進行資料merge操作,其返回型別為boolean。
e)terminate返回最終的聚集函式結果。
package hive.udaf;

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
public class Avg extends UDAF {
         public static class AvgState {
         private long mCount;
         private double mSum;
}

public static class AvgEvaluator implements UDAFEvaluator {
         AvgState state;
         public AvgEvaluator() {
                   super();
                   state = new AvgState();
                   init();
}

/** * init函式類似於建構函式,用於UDAF的初始化 */

public void init() {
         state.mSum = 0;
         state.mCount = 0;
}

/** * iterate接收傳入的引數,並進行內部的輪轉。其返回型別為boolean * * @param o * @return */

public boolean iterate(Double o) {
         if (o != null) {
                   state.mSum += o;
                   state.mCount++;
         } return true;
}

/** * terminatePartial無引數,其為iterate函式輪轉結束後,返回輪轉資料, * terminatePartial類似於hadoop的Combiner * * @return */

public AvgState terminatePartial() {
         // combiner
         return state.mCount == 0 ? null : state;
}

/** * merge接收terminatePartial的返回結果,進行資料merge操作,其返回型別為boolean * * @param o * @return */

public boolean terminatePartial(Double o) {                
         if (o != null) {
                   state.mCount += o.mCount;
                   state.mSum += o.mSum;
         }

         return true;
}

/** * terminate返回最終的聚集函式結果 * * @return */

public Double terminate() {
         return state.mCount == 0 ? null : Double.valueOf(state.mSum / state.mCount);
}

}



5、執行求平均數函式的步驟
a)將java檔案編譯成Avg_test.jar。b)進入hive客戶端新增jar包:hive>add jar /run/jar/Avg_test.jar。c)建立臨時函式:hive>create temporary function avg_test 'hive.udaf.Avg';d)查詢語句:hive>select avg_test(scores.math) from scores;e)銷燬臨時函式:hive>drop temporary function avg_test;


五、總結

1、過載evaluate函式。
2、UDF函式中引數型別可以為Writable,也可為java中的基本資料物件。
3、UDF支援變長的引數。
4、Hive支援隱式型別轉換。
5、客戶端退出時,建立的臨時函式自動銷燬。
6、evaluate函式必須要返回型別值,空的話返回null,不能為void型別。
7、UDF是基於單條記錄的列進行的計算操作,而UDFA則是使用者自定義的聚類函式,是基於表的所有記錄進行的計算操作。
8、UDF和UDAF都可以過載。
9、檢視函式

SHOW FUNCTIONS;

1. UDTF介紹
UDTF(User-Defined Table-Generating Functions) 用來解決 輸入一行輸出多行(On-to-many maping) 的需求。

2. 編寫自己需要的UDTF


(1) 繼承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF。

 (2)實現initialize, process, close三個方法。

UDTF首先會呼叫initialize方法,此方法返回UDTF的返回行的資訊(返回個數,型別)。初始化完成後,會呼叫process方法,對傳入的引數進行處理,可以通過forword()方法把結果返回。最後close()方法呼叫,對需要清理的方法進行清理。

下面是我寫的一個用來切分”key:value;key:value;”這種字串,返回結果為key, value兩個欄位。供參考:

import java.util.ArrayList;
   
    import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
    import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
    import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
    import org.apache.hadoop.hive.ql.metadata.HiveException;
    import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
    import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
    import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
   import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
  
   public class ExplodeMap extends GenericUDTF{
  
       @Override
       public void close() throws HiveException {
           // TODO Auto-generated method stub    
       }
  
       @Override
       public StructObjectInspector initialize(ObjectInspector[] args)
               throws UDFArgumentException {
           if (args.length != 1) {
               throw new UDFArgumentLengthException("ExplodeMap takes only one argument");
           }
           if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
               throw new UDFArgumentException("ExplodeMap takes string as a parameter");
           }
  
           ArrayList<String> fieldNames = new ArrayList<String>();
           ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
           fieldNames.add("col1");
           fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
           fieldNames.add("col2");
           fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
  
           return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,fieldOIs);
       }
  
      @Override
       public void process(Object[] args) throws HiveException {
           String input = args[0].toString();
           String[] test = input.split(";");
           for(int i=0; i<test.length; i++) {
               try {
                   String[] result = test[i].split(":");
                   forward(result);
               } catch (Exception e) {
                  continue;
              }
         }
       }
   }

3. 使用方法

UDTF有兩種使用方法,一種直接放到select後面,一種和lateral view一起使用。

1:直接select中使用

select explode_map(properties) as (col1,col2) from src;

不可以新增其他欄位使用

select a, explode_map(properties) as (col1,col2) from src

不可以巢狀呼叫

select explode_map(explode_map(properties)) from src

不可以和group by/cluster by/distribute by/sort by一起使用

select explode_map(properties) as (col1,col2) from src group by col1, col2


2:和lateral view一起使用

select src.id, mytable.col1, mytable.col2 from src lateral view explode_map(properties) mytable as col1, col2;

此方法更為方便日常使用。執行過程相當於單獨執行了兩次抽取,然後union到一個表裡。






相關推薦

hiveUDFUDAFUDTF使用

Hive進行UDF開發十分簡單,此處所說UDF為Temporary的function,所以需要hive版本在0.4.0以上才可以。一、背景:Hive是基於Hadoop中的MapReduce,提供HQL查詢的資料倉庫。Hive是一個很開放的系統,很多內容都支援使用者定製,包

Hive:自定義函式之UDFUDAFUDTF

hive允許使用者使用自定義函式解決hive 自帶函式無法處理的邏輯。hive自定義函式只在當前執行緒內臨時有效,可以使用shell指令碼呼叫執行hive命令。 UDF 輸入一行資料輸出一行資料。  解決問題描述  想要比較兩個逗號分隔的字串是否相同。  -使用方法  如果

HiveUDFUDAF的使用

UDF使用者自定義函式(user defined function)–針對單條記錄。 建立函式流程 1、自定義一個Java類2、繼承UDF類 3、重寫evaluate方法 4、打成jar包 6、在hive執行add jar方法7、在hive執行建立模板函式 8、hql中使用D

hiveUDFUDAF使用說明

Hive進行UDF開發十分簡單,此處所說UDF為Temporary的function,所以需要hive版本在0.4.0以上才可以。 一、背景:Hive是基於Hadoop中的MapReduce,提供HQL查詢的資料倉庫。Hive是一個很開放的系統,很多內容都支援使用者定製,包括

Hive面試題:udfudafudtf的區別

Hive中有三種UDF:     1、使用者定義函式(user-defined function)UDF;     2、使用者定義聚集函式(user-defined aggregate function,UDAF); &nb

hiveUDF開發:解析json物件解析json陣列物件

hive預設函式: +-------------------------------------------------------------------+ json +--------------

十八Hive UDF程式設計

 依據課程中講解的如何自定義UDF,進行案例編寫,進行總結步驟,並完成額外需求,具體說明如下:1) 依據課程講解UDF程式設計案例,完成練習,總結開發UDF步驟,程式碼貼圖, 給予註釋,重點在於

Hive自定義函式(UDFUDAF)

當Hive提供的內建函式無法滿足你的業務處理需要時,此時就可以考慮使用使用者自定義函式。 UDF 使用者自定義函式(user defined function)–針對單條記錄。 建立函式流程 1、自定義一個Java類 2、繼承UDF類 3、重寫e

JSconstvarlet區別

方法 pre 命令 con 使用 它的 comm 作用 影響 在JavaScript中有三種聲明變量的方式:var、let、const。 1.const 聲明創建一個只讀的常量。這不意味著常量指向的值不可變,而是變量標識符的值只能賦值一次,必須初始化。 const b

如何在 CentOS 7 安裝配置安全加固 FTP 服務

cte success fire lease 註意 tps tran sub linux 步驟 1:安裝 FTP 服務器 1、 安裝 vsftpd 服務器很直接,只要在終端運行下面的命令。 # yum install vsftpd 2、 安裝完成後,服務先是被禁用的,因

《Java瘋狂講義》關聯組合聚合的謬誤

color 有意 sel 面向對象 cal chan nts uci 摘錄 本文參考例如以下資料(建議閱讀): a). difference-aggregation-acquaintance-and-composition-as-used-by-gang-of-f

oracledropdeletetruncate的區別

win style 刪除數據 oracl 數據庫 不能 存在 表空間 結構 oracle中可以使用drop、delete和truncate三個命令來刪除數據庫中的表, 1. delete和truncate都是刪除表中的內容而不能刪除表的結構,而drop則是刪除表的結構和內容

ElasticSearch masterdata client 節點

表示 elastic pan 問題 請求 tro arch 兩個 服務器   在生產環境下,如果不修改elasticsearch節點的角色信息,在高數據量,高並發的場景下集群容易出現腦裂等問題。   默認情況下,elasticsearch 集群中每個節點都有成為主節點的資格

iptablesDNATSNATMASQUERADE的理解

href load pos get eth0 mage 讀取 轉發 wid DNAT(Destination Network Address Translation,目的地址轉換) 通常被叫做目的映謝。而SNAT(Source Network Address Transla

sqldroptruncatedelete的區別

for tro ger view valid 保持 size 引用 gen SQL truncate 、delete與drop區別 相同點: 1.truncate和不帶where子句的delete、以及drop都會刪除表內的數據。 2.drop、truncate都是DD

MySQLDATETIMEDATETIMESTAMP類型的區別

有一個 pda not mat date_add after () day format 一、DATETIME 顯示格式:YYYY-MM-DD HH:MM:SS時間範圍:[ ‘1000-01-01 00:00:00‘到‘9999-12-31 23:59:59‘] 二、DAT

JavascriptNaNnullundefinded的區別

得出 ber 引用 blog log 數據類型 pre 定義 false var a1; var a2 = true; var a3 = 1; var a4 = "Hello"; var a5 = new Object(); var a6 = null; var a7 =

ZBrushMrgbRgbM的使用

按鈕 www zadd mage too get imp load 基礎 ZBrush?軟件工具架中所有的命令選項都是我們平時較為常用的,位於工具架的中間位置,有一個Mrgb、Rgb和M選項它們所表示的是材質及顏色,那麽,在Zbrush中只要選擇相應的選項,就可以同時繪制材

GCC -L-rpath-rpath-link的區別

目錄 恢復 固定 成功 ref exist fyi man手冊 錯誤 GCC 中 -L、-rpath和-rpath-link的區別 來源 http://blog.csdn.net/q1302182594/article/details/42102961 關於這3個參數的說明

jstoLocalString()toString()valueOf()方法

布爾 locals body 值類型 屬於 計算 函數 pos 使用 所有的對象都具有toLocaleString()、toString()和valueOf()方法,toString() 1、Array.toString():將數組轉換成一個字符串,並且返回這個字符串。描述