離線數(shù)據(jù)分析平臺實(shí)戰(zhàn)——140Hive函數(shù)以及自定義函數(shù)講解
Hive函數(shù)介紹
HQL內(nèi)嵌函數(shù)只有195個函數(shù)(包括操作符,使用命令show functions查看)幼驶,基本能夠勝任基本的hive開發(fā)爸邢,但是當(dāng)有較為復(fù)雜的需求的時候怔檩,可能需要進(jìn)行定制的HQL函數(shù)開發(fā)鼓择。
HQL支持三種方式來進(jìn)行功能的擴(kuò)展(只支持使用java編寫實(shí)現(xiàn)自定義函數(shù))兑宇,分別是:UDF(User-Defined Function)启上、UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Table-Generating Function)邢隧。
當(dāng)我們使用java語言進(jìn)行開發(fā)完成后,將生成的jar包移到linux機(jī)器(hive機(jī)器)上,進(jìn)行函數(shù)的創(chuàng)建冈在,然后進(jìn)行使用即可倒慧。
函數(shù)創(chuàng)建命令
HQL函數(shù)的創(chuàng)建一般分為以下幾步:
- 添加jar(0.13.*不支持hdfs上的jar添加,14版本才開始支持)
add jar linux_jar_path
- 創(chuàng)建function包券,語法規(guī)則如下:
create [temporary] function [dbname.]function_name AS class_name;
- 使用function纫谅,和使用其他函數(shù)一樣。
函數(shù)刪除命令
我們可以通過drop命令刪除自定義函數(shù)溅固,語法規(guī)則如下:
drop [temporary] function [if exists] [dbname.]function_name;
自定義UDF介紹
UDF(User-Defined Function)支持一個輸入產(chǎn)生一個輸出系宜,是一個最常用的自定義函數(shù)類型。
實(shí)現(xiàn)自定義UDF要求繼承類org.apache.hadoop.hive.ql.exec.UDF发魄,并且在自定義UDF類中重載實(shí)現(xiàn)evaluate方法盹牧,我們可以通過重載多個evaluate方法達(dá)到函數(shù)參數(shù)多樣化的需求。
實(shí)現(xiàn)案例:
實(shí)現(xiàn)一個大小寫轉(zhuǎn)換的函數(shù)励幼,要求函數(shù)通過參數(shù)的不同決定是進(jìn)行那種轉(zhuǎn)換汰寓,默認(rèn)是轉(zhuǎn)換為小寫。
UDAF介紹
UDAF(User-Defined Aggregate Function)支持多個輸入苹粟,一個輸出有滑。
在原來的版本中可以通過繼承UDAF類來實(shí)現(xiàn)自定義UDAF,但是現(xiàn)在hive已經(jīng)將這個類標(biāo)注為棄用狀態(tài)嵌削。
現(xiàn)在一般通過繼承AbstractGenericUDAFResolver類來實(shí)現(xiàn)自定義UDAF毛好,通過這種方式要求實(shí)現(xiàn)自定義的GenericUDAFEvaluator。
也就是說在現(xiàn)在的hive版本中苛秕,實(shí)現(xiàn)自定義UDAF肌访,那么需要實(shí)現(xiàn)兩個類,分別是AbstractGenericUDAFResolver和GenericUDAFEvaluator艇劫。
AbstractGenericUDAFResolver介紹
AbstractGenericUDAFResolver類主要作用就是根據(jù)hql調(diào)用時候的函數(shù)參數(shù)來獲取具體的GenericUDAFEvaluator實(shí)例對象吼驶,也就是說實(shí)現(xiàn)方法getEvaluator即可,該方法的主要作用就是根據(jù)參數(shù)的不同返回不同的evaluator實(shí)例對象,實(shí)現(xiàn)多態(tài)性。
GenericUDAFEvaluator介紹
GenericUDAFEvaluator類主要作用就是根據(jù)job的不同階段執(zhí)行不同的方法蟹演。
hive通過GenericUDAFEvaluator.Model來確定job的執(zhí)行階段风钻。
PARTIAL1:從原始數(shù)據(jù)到部分聚合,會調(diào)用方法iterate和terminatePartial方法酒请;
PARTIAL2:從部分?jǐn)?shù)據(jù)聚合和部分?jǐn)?shù)據(jù)聚合骡技,會調(diào)用方法merge和terminatePartial;
FINAL:從部分?jǐn)?shù)據(jù)聚合到全部數(shù)據(jù)聚合羞反,會調(diào)用方法merge和terminate布朦;
COMPLETE:從原始數(shù)據(jù)到全部數(shù)據(jù)聚合,會調(diào)用方法iterate和terminate苟弛。
除了上面提到的iterate喝滞、merge阁将、terminate和terminatePartial以外膏秫,還有init(初始化并返回返回值的類型)、getNewAggregationBuffer(獲取新的buffer對象做盅,也就是方法之間傳遞參數(shù)的對象)缤削,reset(重置buffer對象)。
UDAF案例
實(shí)現(xiàn)一個自定義的sum函數(shù)吹榴。要求函數(shù)支持整形和浮點(diǎn)型的sum操作亭敢。
UDTF介紹
UDTF(User-Defined Table-Generating Function)支持一個輸入多個輸出。
一般用于解析工作图筹,比如說解析url帅刀,然后獲取url中的信息。要求繼承類org.apache.hadoop.hive.ql.udf.generic.GenericUDTF远剩,
實(shí)現(xiàn)方法:
initialize(返回返回值的參數(shù)類型)扣溺、process具體的處理方法,一般在這個方法中會調(diào)用父類的forward方法進(jìn)行數(shù)據(jù)的寫出瓜晤、close關(guān)閉資源方法锥余,最終會調(diào)用close方法,同MR程序中的cleanUp方法痢掠。
實(shí)現(xiàn)功能:解析爬蟲數(shù)據(jù)驱犹,從數(shù)據(jù)中讀取產(chǎn)品id、產(chǎn)品名稱足画、價格雄驹。
常用的三種集成自定義函數(shù)的方式
首先要求創(chuàng)建的function是永久function,不能是臨時function淹辞。
第一種:修改hive-site.xml文件荠医,添加參數(shù)hive.aux.jars.path,value為jar包的linux本地路徑,要求是以file:///開頭的絕對路徑彬向。
第二種:直接將jar包移動到hive的lib文件夾中兼贡。
第三種:將jar包移動到hdfs上,然后在創(chuàng)建function的時候指定function使用的hdfs上的jar文件絕對路徑(包括hdfs://hh:8020/前綴)娃胆,這樣在使用的時候遍希,hive會自動將jar下載到本地進(jìn)行緩存的。
另外一種hive集成自定義函數(shù)的方式
我們可以通過修改hive的源碼里烦,進(jìn)行自定義函數(shù)的添加凿蒜,添加完成后,我們就不需要再手動創(chuàng)建函數(shù)胁黑。添加步驟如下:
- 假設(shè)自定義函數(shù)的整個包名為com.beifeng.ql.udf.UDFTest, jar文件為beifengUserUDF.jar废封。將該jar包移動到hive的lib文件夾中。
- 修改hive源文件$HIVE_HOME/src/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java丧蘸,添加import com.beifeng.ql.udf.UDFTest; registerUDF("test", UDFTest.class,false);
- 編譯hive后漂洋,進(jìn)行jar包的替換,然后就可以使用函數(shù)了力喷。