Hive使用者自定義聚合函式(UDAF)
使用者自定義聚合函式,使用者提供的多個入參通過聚合計算(求和、求最大值、求最小值)得到一個聚合計算結果的函式。
問題:UDF也可以提供輸入多個引數然後輸出一個結果的運算,比如加法運算add(3,5),add這個UDF需要實現UDF的evaluate方法,那麼UDF和UDAF的實質分別究竟是什麼?
Java程式碼- Double evaluate(Double a, Double b)
1.什麼是UDAF
UDF只能實現一進一出的操作,如果需要實現多進一出,則需要實現UDAF。比如: Hive查詢資料時,有些聚類函式在HQL沒有自帶,需要使用者自定義實現; 使用者自定義聚合函式: Sum, Average
2.實現UFAF的步驟
- 引入如下兩下類
- import org.apache.hadoop.hive.ql.exec.UDAF
- import org.apache.hadoop.hive.ql.exec.UDAFEvaluator
- 函式類需要繼承UDAF類,計算類Evaluator實現UDAFEvaluator介面
- Evaluator需要實現UDAFEvaluator的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返回最終的聚集函式結果。
3.例項
計算平均數
Java程式碼- 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
- 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 merge(AvgState avgState) {
- if (avgState != null) {
- state.mCount += avgState.mCount;
- state.mSum += avgState.mSum;
- }
- return true;
- }
- /**
- * terminate返回最終的聚集函式結果 * * @return
- */
- public Double terminate() {
- return state.mCount == 0 ? null : Double.valueOf(state.mSum / state.mCount);
- }
- }
- }
4. Hive中使用UDAF
- 將java檔案編譯成udaf_avg.jar
- 進入hive客戶端新增jar包
- hive>add jar /home/hadoop/udaf_avg.jar
- 建立臨時函式
- hive>create temporary function udaf_avg 'hive.udaf.Avg'
- 查詢語句
- hive>select udaf_avg(people.age) from people
- 銷燬臨時函式
- hive>drop temporary function udaf_avg
5. 總結
通過上面的介紹,可以看到UDAF的用法與UDF的區別了,UDF雖然可以接收多個入參,但是引數個數是固定的(其實也可以不固定,只要evaluate方法的引數型別是變長引數即可,但是一般不這麼用),而UDAF的入參是元素個數不固定的集合,這個集合只要可遍歷(使用Evaluator的iterate方法遍歷)即可,上面的入參是people表的所有age列。
UDF是對只有單條記錄的列進行的計算操作,而UDFA則是使用者自定義的聚類函式,是基於表的所有記錄進行的計算操作。