Hive函數以及自定義函數講解(UDF)
Hive函數介紹
HQL內嵌函數只有195個函數(包括操作符,使用命令show functions查看),基本能夠勝任基本的hive開發,但是當有較為復雜的需求的時候,可能需要進行定制的HQL函數開發。HQL支持三種方式來進行功能的擴展(只支持使用java編寫實現自定義函數),分別是:UDF(User-Defined Function)、UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Table-Generating Function)。當我們使用java語言進行開發完成後,將生成的jar包移到linux機器(hive機器)上,進行函數的創建,然後進行使用即可。
函數創建命令
HQL函數的創建一般分為以下幾步:
1. 添加jar(0.13.*不支持hdfs上的jar添加,14版本才開始支持)
add jar linux_jar_path
add jar /home/hadoop/bigdatasoftware/datas/hive-1.0-SNAPSHOT.jar
2. 創建function,語法規則如下:
create [temporary] function [dbname.]function_name AS class_name;
create temporary function myfuntion as ‘com.gec.demo.LowerUDF‘;
3. 使用function,和使用其他函數一樣。
函數刪除命令
我們可以通過drop命令刪除自定義函數,語法規則如下:
drop [temporary] function [if exists] [dbname.]function_name;
自定義UDF介紹
UDF(User-Defined Function)支持一個輸入產生一個輸出,是一個最常用的自定義函數類型。實現自定義UDF要求繼承類org.apache.hadoop.hive.ql.exec.UDF,並且在自定義UDF類中重載實現evaluate方法,我們可以通過重載多個evaluate方法達到函數參數多樣化的需求。
實現案例:實現一個大小寫轉換的函數,要求函數通過參數的不同決定是進行那種轉換,默認是轉換為小寫。
UDAF介紹
UDAF(User-Defined Aggregate Function)支持多個輸入,一個輸出。在原來的版本中可以通過繼承UDAF類來實現自定義UDAF,但是現在hive已經將這個類標註為棄用狀態。現在一般通過繼承AbstractGenericUDAFResolver類來實現自定義UDAF,通過這種方式要求實現自定義的GenericUDAFEvaluator。也就是說在現在的hive版本中,實現自定義UDAF,那麽需要實現兩個類,分別是AbstractGenericUDAFResolver和GenericUDAFEvaluator。
AbstractGenericUDAFResolver介紹
AbstractGenericUDAFResolver類主要作用就是根據hql調用時候的函數參數來獲取具體的GenericUDAFEvaluator實例對象,也就是說實現方法getEvaluator即可,該方法的主要作用就是根據參數的不同返回不同的evaluator實例對象,實現多態性。
maven依賴配置如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>BigdataStudy</artifactId> <groupId>com.gec.demo</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>hive</artifactId> <name>hive</name> <!-- FIXME change it to the project‘s website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <hadoop.version>2.7.2</hadoop.version> <!--<hive.version> 0.13.1</hive.version>--> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.7.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>0.13.1</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>0.13.1</version> </dependency> </dependencies> </project>
自定義的函數如下:
package com.gec.demo; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class LowerUDF extends UDF { public Text evaluate(Text str){ if (null==str.toString()){ return null; } return new Text(str.toString().toLowerCase()); } public static void main(String[] args) { System.out.println(new LowerUDF().evaluate(new Text("HIVE"))); } }
然後打包jar包,
將jar包發送到Linux的/home/hadoop/bigdatasoftware/datas目錄下
GenericUDAFEvaluator介紹
GenericUDAFEvaluator類主要作用就是根據job的不同階段執行不同的方法。hive通過GenericUDAFEvaluator.Model來確定job的執行階段。PARTIAL1:從原始數據到部分聚合,會調用方法iterate和terminatePartial方法;PARTIAL2:從部分數據聚合和部分數據聚合,會調用方法merge和terminatePartial;FINAL:從部分數據聚合到全部數據聚合,會調用方法merge和terminate;COMPLETE:從原始數據到全部數據聚合,會調用方法iterate和terminate。除了上面提到的iterate、merge、terminate和terminatePartial以外,還有init(初始化並返回返回值的類型)、getNewAggregationBuffer(獲取新的buffer對象,也就是方法之間傳遞參數的對象),reset(重置buffer對象)。
UDTF介紹
UDTF(User-Defined Table-Generating Function)支持一個輸入多個輸出。一般用於解析工作,比如說解析url,然後獲取url中的信息。要求繼承類org.apache.hadoop.hive.ql.udf.generic.GenericUDTF,實現方法:initialize(返回返回值的參數類型)、process具體的處理方法,一般在這個方法中會調用父類的forward方法進行數據的寫出、close關閉資源方法,最終會調用close方法,同MR程序中的cleanUp方法。
實現功能:解析爬蟲數據,從數據中讀取產品id、產品名稱、價格。
常用的三種集成自定義函數的方式
首先要求創建的function是永久function,不能是臨時function。
第一種:修改hive-site.xml文件,添加參數hive.aux.jars.path,value為jar包的linux本地路徑,要求是以file:///開頭的絕對路徑。
第二種:直接將jar包移動到hive的lib文件夾中。
第三種:將jar包移動到hdfs上,然後在創建function的時候指定function使用的hdfs上的jar文件絕對路徑(包括hdfs://hh:8020/前綴),這樣在使用的時候,hive會自動將jar下載到本地進行緩存的。
Hive函數以及自定義函數講解(UDF)