Hive自訂函數UDF、UDTF、UDAF入門

來源:互聯網
上載者:User

Hive自訂函數UDF、UDTF、UDAF入門

詳細講解Hive自訂函數UDF、UDTF、UDAF基礎知識,帶你快速入門,首先在Hive中建立表”apache_log”

CREATE TABLE apachelog (
  host STRING,
  identity STRING,
  user STRING,
  time STRING,
  request STRING,
  status STRING,
  size STRING,
  referer STRING,
  agent STRING)
ROW FORMAT SERDE 'org.apache.Hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]*\\]]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*) (?: ([^ \"]*|\".*\") ([^ \"]*|\".*\"))?"
)
STORED AS TEXTFILE;

這個是官方給出的執行個體,但是是錯的。

不過,已經有人給做出了修改。

接下來結合一些範例資料

27.19.74.143 - - [29/April/2016:17:38:20 +0800] "GET /static/image/common/faq.gif HTTP/1.1" 200 1127
110.52.250.126 - - [29/April/2016:17:38:20 +0800] "GET /data/cache/style_1_widthauto.css?y7a HTTP/1.1" 200 1292
27.19.74.143 - - [29/April/2016:17:38:20 +0800] "GET /static/image/common/hot_1.gif HTTP/1.1" 200 680
27.19.74.143 - - [29/April/2016:17:38:20 +0800] "GET /static/image/common/hot_2.gif HTTP/1.1" 200 682
27.19.74.143 - - [29/April/2016:17:38:20 +0800] "GET /static/image/filetype/common.gif HTTP/1.1" 200 90
110.52.250.126 - - [29/April/2016:17:38:20 +0800] "GET /source/plugin/wsh_wx/img/wsh_zk.css HTTP/1.1" 200 1482
110.52.250.126 - - [29/April/2016:17:38:20 +0800] "GET /data/cache/style_1_forum_index.css?y7a HTTP/1.1" 200 2331
110.52.250.126 - - [29/April/2016:17:38:20 +0800] "GET /source/plugin/wsh_wx/img/wx_jqr.gif HTTP/1.1" 200 1770
27.19.74.143 - - [29/April/2016:17:38:20 +0800] "GET /static/image/common/recommend_1.gif HTTP/1.1" 200 1028
110.52.250.126 - - [29/April/2016:17:38:20 +0800] "GET /static/image/common/logo.png HTTP/1.1" 200 4542
......

這個是apache伺服器的日誌資訊,一共七個欄位,分別表示:”host”、”identity”、”user”、”time”、”request”、”status”、”size”,在hive官網上是有九個欄位的,剩下兩個為:”referer”、”agent”。

------------------------------------------分割線------------------------------------------

範例資料相關資料可從以下資訊得到下載:

點擊這個 連結關注 幫客之家官方,關注後回複數字151443。即可得到網友的分享密碼。

如果取消追蹤幫客之家公眾號,即使再次關注,也將無法提供本服務!

連結:https://pan.baidu.com/s/1dvBorZch0WFPMPO2xqZTLQ 密碼:獲得見上面的方法,地址失效請在下面留言。

------------------------------------------分割線------------------------------------------

我們根據這些資料,從一些小需求中來體會一下這三種函數。

UDF(user-defined functions)
“小”需求:
 提取”time”,轉換成”yyyy-MM-dd HH:mm:ss” 格式。

要點:
1.繼承自“org.apache.hadoop.hive.ql.exec.UDF”;
2.實現”evaluate()”方法。

*JAVA 代碼*
package com.hadoop.hivetest.udf;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

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

public class MyDateParser extends UDF{
    public String evaluate(String s){
        SimpleDateFormat formator = new SimpleDateFormat("dd/MMMMM/yyyy:HH:mm:ss Z",Locale.ENGLISH);
        if(s.indexOf("[")>-1){
            s = s.replace("[", "");
        }
        if(s.indexOf("]")>-1){
            s = s.replace("]", "");
        }

        try {
            //將輸入的string轉換成date資料類型
            Date date = formator.parse(s);
            SimpleDateFormat rformator = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return rformator.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
    }
}

小插曲
匯出為jar包,發送到Linux上。這次我們可以使用 editplus 編輯器來上傳:

– 開啟editplus,選擇”File—FTP—FTP Setting” –

– 選擇添加 –

並且在相應的欄位上填上值,對於”Subdirectory”這一項要填寫的是你希望上傳到Linux上的哪個目錄。

– 點擊”Advanced Options” –

之後便可以一路OK回去。

– 選擇FTP Upload –

在這裡找到要上傳的檔案,選擇要上傳到哪一個賬戶上,並選擇”Upload”即可。

然後我們就可以在”Subdirectory”中寫到的目錄下去找我們的檔案了。

– 小插曲結束 –

之後我們使用beeline用戶端來串連hive

然後我們可以建立一個資料庫,並使用之前的建表語句來建立”apache_log”,並匯入資料(預設大家都會了^.^)。

Step 1: add jar “jar-path”

Step 2: create function timeparse as ‘包名+類名’

Step 3: 使用該函數

對比之前我們匯入的資料

UDTF(user-defined table-generating functions)
“小”需求:
針對”request”欄位,將其拆分,擷取到使用者的請求串連。
第一部分表示請求的方式,第二部分為使用者請求的串連,第三部分為協及版本號碼。

要點:
1.繼承自”org.apache.hadoop.hive.ql.udf.generic.GenericUDTF”;
2.實現initialize()、process()、close()三個方法。

*JAVA代碼
package com.hadoop.hivetest.udf;

import java.util.ArrayList;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
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 MyRequestParser extends GenericUDTF {

    @Override
    public StructObjectInspector initialize(ObjectInspector[] arg0) throws UDFArgumentException {
        if(arg0.length != 1){
            throw new UDFArgumentException("參數不正確。");
        }
        ArrayList<String> fieldNames = new ArrayList<String>();
        ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();

        //添加返回欄位設定
        fieldNames.add("rcol1");
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        fieldNames.add("rcol2");
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        fieldNames.add("rcol3");
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        //將返回欄位設定到該UDTF的傳回值類型中
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs); 
    }
    @Override
    public void close() throws HiveException {

    }

    //處理函數的輸入並且輸出結果的過程
    @Override
    public void process(Object[] args) throws HiveException {
        String input = args[0].toString();

        input = input.replace("\"", "");

        String[] result = input.split(" ");
        //如果解析錯誤或失敗,則返回三個欄位內容都是"--"
        if(result.length != 3){
            result[0] = "--";
            result[1] = "--";
            result[2] = "--";
        }
        forward(result);
    }
}

依照上面的步驟,匯出jar包,上傳到Linux伺服器上。在此不再贅述,其實是攢著另一種上傳檔案的方式,下次教給大家。

Step 1: add jar “jar-path”

Step 2: create function requestparse as ‘包名+類名’

Step 3: 使用該函數

對比我們之前置入的資料

UDAF(user-defined aggregation functions)
“小”需求:
求出最大的流量值

要點:
1.繼承自”org.apache.hadoop.hive.ql.exec.UDAF”;
2.自訂的內部類要實現介面”org.apache.hadoop.hive.ql.exec.UDAFEvaluator”;
3.要實現iterate()、terminatePartial()、merge()、terminate()四個方法。

*JAVA代碼
package com.hadoop.hivetest.udf;

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;

@SuppressWarnings("deprecation")
public class MaxFlowUDAF extends UDAF {

    public static class MaxNumberUDAFEvaluator implements UDAFEvaluator{
        private IntWritable result;
        public void init() {
            result = null;
        }

        //彙總的多行中每行的被彙總的值都會被調用interate方法,所以這個方法裡面我們來定義彙總規則
        public boolean iterate(IntWritable value){
            if(value == null){
                return false;
            }
            if(result == null){
                result = new IntWritable(value.get());
            }else{
                //需求是求出流量最大值,在這裡進行流量的比較,將最大值放入result
                result.set(Math.max(result.get(), value.get()));
            }
            return true;
        }

        //hive需要部分彙總結果時會調用該方法,返回當前的result作為hive取部分彙總值得結果
        public IntWritable terminatePartial(){
            return result;
        }

        //彙總值,新行未被處理的值會調用merge加入彙總,這裡直接調用上面定義的彙總規則方法iterate
        public boolean merge(IntWritable other){
            return iterate(other);
        }

        //hive需要最後總彙總結果時調用的方法,返回彙總的最終結果
        public IntWritable terminate(){
            return result;
        }
    }
}

匯出jar包,上傳到Linux伺服器…

Step 1: add jar ‘jar-path’

Step 2: create function maxflow as ‘包名+類名’

Step 3: 使用該函數

於是此時,hive便會將sql語句轉換為mapreduce任務去執行了。

當我們建立函數之後,得出的結果卻不是想要的結果的時候,我們將Java代碼修改之後,重新打了包上傳過來,也重新加到了hive的classpath中,但是新建立出來的函數得出的結果跟修改之前的一樣。這個因為新修改過後的類名與之前的類名重複了,在當前session中會優先以之前的來建立函數。此時有兩種辦法解決,一是斷開當前的串連,重新使用beeline用戶端登陸一次,還有就是將修改後的Java類改一個名稱,重新匯入,使用新的Java類來建立函數。

當然,這些才都只是 UDF 的小皮毛,我們可以發現,通過自訂函數,我們可以省去寫很多sql,並且通過使用api,我們可以更隨意的操作資料庫裡的欄位,實現多種計算和統計。 

Hive編程指南 PDF 中文高清版  https://www.bkjia.com/Linux/2015-01/111837.htm
基於Hadoop叢集的Hive安裝 https://www.bkjia.com/Linux/2013-07/87952.htm
Hive內表和外表的區別 https://www.bkjia.com/Linux/2013-07/87313.htm
Hadoop + Hive + Map +reduce 叢集安裝部署 https://www.bkjia.com/Linux/2013-07/86959.htm
Hive本地獨立模式安裝 https://www.bkjia.com/Linux/2013-06/86104.htm
Hive學習之WordCount單詞統計 https://www.bkjia.com/Linux/2013-04/82874.htm
Hive運行架構及配置部署 https://www.bkjia.com/Linux/2014-08/105508.htm
Hive 2.1.1安裝配置詳解  https://www.bkjia.com/Linux/2017-04/143053.htm
Hive安裝及與HBase的整合  https://www.bkjia.com/Linux/2016-12/138721.htm

Hive 的詳細介紹:請點這裡
Hive 的:請點這裡

本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151443.htm

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.