1. 程式人生 > >大資料入門教程系列之Hive內建函式及自定義函式

大資料入門教程系列之Hive內建函式及自定義函式

本篇文章主要介紹Hive內建函式以及自定義UDF函式和UDFT函式,自定義UDF函式通過一個國際轉換中文的例子說明。

操作步驟:

①、準備資料和環境

②、演示Hive內建函式

③、自定義UDF函式編寫、演示

 

詳細步驟:

一、準備資料和環境(需啟動Hadoop)

注:環境和程式基於上一篇java api操作hive:大資料入門教程系列之Hive的Java API 操作

ctrl+l可以清楚視窗操作的命令

1、建立表

create table teacher(
id int,
name string,
sex string,
age int,
nationality string
)
row format delimited fields terminated by ',';

 

2、準備資料

vim teacher.txt

1,zhangsan,man,23,CN
2,lisi,woman,33,HK
3,wangwu,man,18,BRA

 

3、插入資料,執行插入資料有點慢,等待即可

load data local inpath '/home/hadoop/teacher.txt' into table teacher;

 

插入後查詢:

select * from teacher;

二、hive內建函式

1、使用如下命令檢視當前hive版本支援的所有內建函式

show functions;

 

2、可以使用如下命令檢視某個函式的使用方法及作用,比如檢視 and函式

desc function and;

 

3、如果想要檢視更為詳細的資訊加上extended引數

desc function extended and;

4、演示小寫轉大寫,查詢老師把名字轉大寫

 select id,upper(name),sex,age from teacher;

 

 

三、自定義UDF函式

雖然hive中為我們提供了很多的內建函式,但是在實際工作中,有些情況下hive提供的內建函式無法滿足我們的需求,就需要我們自己來手動編寫,所以就有了自定義函式 UDF。

UDF分為三種,分別如下

(1).UDF(User-Defined-Function),一進一出(輸入一行,輸出一行),比如:upper()、lowser()等。

(2).UDAF(User-Defined Aggregation Funcation),多進一出(輸入多行,輸出一行),比如:avg()、sum()等。

(3).UDTF(User-Defined Table-Generating Functions),一進多出(輸入一行,輸出多行),比如:collect_set()、collect_list()等。

官方文件:https://cwiki.apache.org/confluence/display/Hive/HivePlugins

1、使用自定義函式需要引入hive-exec的依賴

<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>2.3.0</version>
</dependency>

2、UDF程式設計模型: 

(1).繼承 org.apache.hadoop.hive.ql.exec.UDF 

(2).實現 evaluate() 方法

實現需求:自定義UDF函式,轉換國籍為中文

比如:輸入CN,輸出中國大陸

程式碼如下:

package udf;

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

import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.io.Text;

/**
 * UDF自定義函式國籍轉換
 * Created by zhoujh on 2018/10/18.
 */
public class UDFNationality extends UDF {

    //我們要實現的業務邏輯非常簡單,就是傳過來一個英文的國家名,然後返回一箇中文,它們的對映關係肯定事先就定義好了,
     //不可能等到呼叫的時候了才建立對映關係。
    public static Map<String,String> nationMap=new HashMap<String,String>();
    static {
        nationMap.put("CN", "中國");
        nationMap.put("HK", "香港");
        nationMap.put("BRA", "巴西");
    }

    //之所以使用Text作為返回值是因為這個方法是要在HDFS上執行的,HDFS上沒有String型別,取而代之的是Text,因此我們需要使用Text作為返回值。
    Text text=new Text();
    //重寫UDF,就是要寫evaluate方法,注意方法名一定得是這個。這個方法是非常靈活的,引數可以有多個,返回值如果想要多個的話,可以封裝成一個物件。
    public Text evaluate(Text nation){
        //先得到傳過來的英文的國家名
        String nation_e=nation.toString();
        //根據英文名得到中文名
        String nation_str=nationMap.get(nation_e);
        if(nation_str==null){
            //如果得到的值是null,說明沒有對應的對映關係,我們就輸出預設中國人
            text.set("中國人");
            return text;
        }
        text.set(nation_str);
        return text;
    }
}

3、自定義函式有4種使用方式,下面分別介紹

①、臨時函式,只能在當前客戶端使用

一、將我們剛剛編寫完成的程式碼,打成jar

二、先使用xftp上傳到伺服器,再將jar包上傳到hive

 

三、把jar新增到hive

add jar /home/hadoop/java-api-hive-1.0-SNAPSHOT.jar;

四、建立函式

create temporary function cvnationality as 'udf.UDFNationality';

五、檢視建立的函式cvnationality

show functions;

六、檢視函式cvnationality的詳細資訊

這裡可以看到你java類裡面的@Description註解我沒寫

 

七、使用函式

select id,name,sex,age,cvnationality(nationality) from teacher;

②、臨時函式,只能在當前客戶端使用

在$HIVE_HOME下新建目錄auxlib,將jar拷貝到該目錄下,重啟hadoop

建立函式cvnationality

檢視建立的函式,同上

使用函式,效果同上

select id,name,sex,age,cvnationality(nationality) from teacher;

 

③、永久函式,建立後可以在任意客戶端使用,建議使用

一、上傳jar到hdfs

hadoop fs -put java-api-hive-1.0-SNAPSHOT.jar  /libs

 

 

二、建立函式 cvnationality2

create function cvnationality2 as 'udf.UDFNationality' using jar 'hdfs://node1:9000/libs/java-api-hive-1.0-SNAPSHOT.jar';

注意:建立完function之後,通過show functions並沒有看到我們自定義的函式cvnationality2,但是可以使用

三、使用函式,效果同上

 select id,name,sex,age,default.cvnationality2(nationality) from teacher;

④、永久函式,將自定義函式整合到hive原始碼中

使用這種方式需要修改hive的原始碼,整合到hive原始碼後,hive啟動後就可以使用,不用再向hive中註冊函式,相當於一個hive的內建函式。如果公司有自己的大資料框架版本,建議使用這種方式。

 

一、從官網下載hive原始碼,筆者使用的版本為2.3.0,http://apache.fayea.com/hive/

 

二、下載後解壓

tar -zxvf apache-hive-2.3.0-src.tar.gz

將自定義UDF函式繼承到Hive原始碼中,需要如下三個步驟

 

三、上傳檔案

把GenericUDFHello.java類上傳到如下目錄,並修改包名

 

四、配置FunctionRegistry類

hive 中有一個非常重要的類FunctionRegistry,我們需要將自己自定義的函式在這個類中配置,引入我們自定義函式類GenericUDFHello

 

註冊自定義函式類GenericUDFHello,輸入static { 搜尋,在靜態程式碼塊中註冊我們編寫的自定義函式,這裡面都是hive的所有內建函式,新增如下程式碼

 

五、編譯 Hive 原始碼

cd apache-hive-2.3.0-src

mvn clean package -Phadoop-2,dist -DskipTests

編譯過程教程,請耐心等待,編譯完成後,hive會生成一個壓縮包,解壓配置後就可以使用,hive壓縮包存放的路徑是apache-hive-2.3.0-src/packaging/target

使用函式hello(效果同上)