溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

udf、udaf、udtf怎么用

發(fā)布時間:2021-12-16 15:05:32 來源:億速云 閱讀:231 作者:小新 欄目:云計算

小編給大家分享一下udf、udaf、udtf怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

一、UDF

1、背景:Hive是基于Hadoop中的MapReduce,提供HQL查詢的數(shù)據(jù)倉庫。Hive是一個很開放的系統(tǒng),很多內(nèi)容都支持用戶定制,包括:

a)文件格式:Text File,Sequence File

b)內(nèi)存中的數(shù)據(jù)格式: Java Integer/String, Hadoop IntWritable/Text

c)用戶提供的 map/reduce 腳本:不管什么語言,利用 stdin/stdout 傳輸數(shù)據(jù)

d)用戶自定義函數(shù): Substr, Trim, 1 – 1

e)用戶自定義聚合函數(shù): Sum, Average…… n – 1

2、定義:UDF(User-Defined-Function),用戶自定義函數(shù)對數(shù)據(jù)進行處理。

二、用法

1、UDF函數(shù)可以直接應(yīng)用于select語句,對查詢結(jié)構(gòu)做格式化處理后,再輸出內(nèi)容。

2、編寫UDF函數(shù)的時候需要注意一下幾點:

a)自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。

b)需要實現(xiàn)evaluate函。

c)evaluate函數(shù)支持重載。

3、以下是兩個數(shù)求和函數(shù)的UDF。evaluate函數(shù)代表兩個整型數(shù)據(jù)相加,兩個浮點型數(shù)據(jù)相加,可變長數(shù)據(jù)相加。

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)創(chuàng)建臨時函數(shù):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)銷毀臨時函數(shù):hive> DROP TEMPORARY FUNCTION add_example;

5、細節(jié)在使用UDF的時候,會自動進行類型轉(zhuǎn)換,例如:

SELECT add_example(8,9.1) FROM scores;

結(jié)果是17.1,UDF將類型為Int的參數(shù)轉(zhuǎn)化成double。類型的飲食轉(zhuǎn)換是通過UDFResolver來進行控制的。

三、UDAF

1、Hive查詢數(shù)據(jù)時,有些聚類函數(shù)在HQL沒有自帶,需要用戶自定義實現(xiàn)。

2、用戶自定義聚合函數(shù): 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、函數(shù)類需要繼承UDAF類,內(nèi)部類Evaluator實UDAFEvaluator接口。

3、Evaluator需要實現(xiàn) init、iterate、terminatePartial、merge、terminate這幾個函數(shù)。

a)init函數(shù)實現(xiàn)接口UDAFEvaluator的init函數(shù)。

b)iterate接收傳入的參數(shù),并進行內(nèi)部的輪轉(zhuǎn)。其返回類型為boolean。

c)terminatePartial無參數(shù),其為iterate函數(shù)輪轉(zhuǎn)結(jié)束后,返回輪轉(zhuǎn)數(shù)據(jù),terminatePartial類似于hadoop的Combiner。

d)merge接收terminatePartial的返回結(jié)果,進行數(shù)據(jù)merge操作,其返回類型為boolean。

e)terminate返回最終的聚集函數(shù)結(jié)果。

4、以下為一個求平均數(shù)的UDAF:

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函數(shù)類似于構(gòu)造函數(shù),用于UDAF的初始化
      */
     public void init() {
        state.mSum = 0;
        state.mCount = 0;
     }

     /**
      * iterate接收傳入的參數(shù),并進行內(nèi)部的輪轉(zhuǎn)。其返回類型為boolean
      * 
      * @param o
      * @return
      */
     public boolean iterate(Double o) {
        if (o != null) {
          state.mSum += o;
          state.mCount++;
        }
        return true;
     }

     /**
      * terminatePartial無參數(shù),其為iterate函數(shù)輪轉(zhuǎn)結(jié)束后,返回輪轉(zhuǎn)數(shù)據(jù),
      * terminatePartial類似于hadoop的Combiner
      * 
      * @return
      */
     public AvgState terminatePartial() {// combiner
        return state.mCount == 0 ? null : state;
     }

     /**
      * merge接收terminatePartial的返回結(jié)果,進行數(shù)據(jù)merge操作,其返回類型為boolean
      * 
      * @param o
      * @return
      */
     public boolean merge(AvgState o) {
        if (o != null) {
          state.mCount += o.mCount;
          state.mSum += o.mSum;
        }
        return true;
     }

     /**
      * terminate返回最終的聚集函數(shù)結(jié)果
      * 
      * @return
      */
     public Double terminate() {
        return state.mCount == 0 ? null : Double.valueOf(state.mSum
             / state.mCount);
     }
   }
}
5、執(zhí)行求平均數(shù)函數(shù)的步驟

a)將java文件編譯成Avg_test.jar。

b)進入hive客戶端添加jar包:

hive>add jar /run/jar/Avg_test.jar。

c)創(chuàng)建臨時函數(shù):

hive>create temporary function avg_test 'hive.udaf.Avg';

d)查詢語句:

hive>select avg_test(scores.math) from scores;

e)銷毀臨時函數(shù):

hive>drop temporary function avg_test;

五、總結(jié)

1、重載evaluate函數(shù)。

2、UDF函數(shù)中參數(shù)類型可以為Writable,也可為java中的基本數(shù)據(jù)對象。

3、UDF支持變長的參數(shù)。

4、Hive支持隱式類型轉(zhuǎn)換。

5、客戶端退出時,創(chuàng)建的臨時函數(shù)自動銷毀。

6、evaluate函數(shù)必須要返回類型值,空的話返回null,不能為void類型。

7、UDF是基于單條記錄的列進行的計算操作,而UDFA則是用戶自定義的聚類函數(shù),是基于表的所有記錄進行的計算操作。

8、UDF和UDAF都可以重載。

9、查看函數(shù)

SHOW FUNCTIONS; 
DESCRIBE FUNCTION <function_name>;

 

UDTF步驟:

1.必須繼承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
2.實現(xiàn)initialize, process, close三個方法
3.UDTF首先會
     a.調(diào)用initialize方法,此方法返回UDTF的返回行的信息(返回個數(shù),類型)
     b.初始化完成后,會調(diào)用process方法,對傳入的參數(shù)進行處理,可以通過forword()方法把結(jié)果返回
     c.最后close()方法調(diào)用,對需要清理的方法進行清理


Java代碼 

public class GenericUDTFExplode extends GenericUDTF {  

  

  private ListObjectInspector listOI = null;  

  

  @Override  

  public void close() throws HiveException {  

  }  

  

  @Override  

  public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException {  

    if (args.length != 1) {  

      throw new UDFArgumentException("explode() takes only one argument");  

    }  

  

    if (args[0].getCategory() != ObjectInspector.Category.LIST) {  

      throw new UDFArgumentException("explode() takes an array as a parameter");  

    }  

    listOI = (ListObjectInspector) args[0];  

  

    ArrayList<String> fieldNames = new ArrayList<String>();  

    ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();  

    fieldNames.add("col");  

    fieldOIs.add(listOI.getListElementObjectInspector());  

    return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,  

        fieldOIs);  

  }  

  

  private final Object[] forwardObj = new Object[1];  

  

  @Override  

  public void process(Object[] o) throws HiveException {  

    List<?> list = listOI.getList(o[0]);  

    if(list == null) {  

      return;  

    }  

    for (Object r : list) {  

      forwardObj[0] = r;  

      forward(forwardObj);  

    }  

  }  

  

  @Override  

  public String toString() {  

    return "explode";  

  }  

10、wiki鏈接:http://wiki.apache.org/hadoop/Hive/LanguageManual/UDF

Deploying Jars for User Defined Functions and User Defined SerDes

In order to start using your UDF, you first need to add the code to the classpath:

hive> add jar my_jar.jar;

Added my_jar.jar to class path

By default, it will look in the current directory. You can also specify a full path:

hive> add jar /tmp/my_jar.jar;

Added /tmp/my_jar.jar to class path

Your jar will then be on the classpath for all jobs initiated from that session. To see which jars have been added to the classpath you can use:

hive> list jars;

my_jar.jar

See Hive CLI for full syntax and more examples.

As of Hive 0.13, UDFs also have the option of being able to specify required jars in the CREATE FUNCTION statement:

CREATE FUNCTION myfunc AS 'myclass' USING JAR 'hdfs:///path/to/jar';

This will add the jar to the classpath as if ADD JAR had been called on that jar. 

以上是“udf、udaf、udtf怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI