大資料入門教程系列之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(效果同上)