虽然hive中为我们提供了很多的内置函数,但是在实际工作中,有些情况下hive提供的内置函数无法满足我们的需求,就需要我们自己来手动编写,所以就有了自定义函数 UDF。
一、自定义函数分类
UDF分为三种,分别如下:
1、UDF(User-Defined-Function),一进一出(输入一行,输出一行),比如:upper()、lower()等。
UDF编程模型:
- 继承 org.apache.hadoop.hive.ql.exec.UDF
- 实现 evaluate() 方法
2、UDAF(User-Defined Aggregation Funcation),多进一出(输入多行,输出一行),比如:avg()、sum()等。
UDAF编程模型:
- 继承 org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver;
- 实现 evaluate() 方法
- 编写静态内部类(函数的计算逻辑),继承GenericUDAFEvaluator,必须重写如下方法
3、UDTF(User-Defined Table-Generating Functions),一进多出(输入一行,输出多行),比如:collect_set()、collect_list()等。
UDAF编程模型:
- 继承 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
- 实现三个方法 initialize()、process()、close()
官方文档:https://cwiki.apache.org/confluence/display/Hive/HivePlugins
使用自定义函数需要引入hive-exec的依赖
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.0</version>
</dependency>
二、自定义函数使用方法
1、通过上传到hdfs使用
- 上传jar到hdfs
$ hadoop fs -put hive-1.0-SNAPSHOT.jar /libs
- 创建函数 say_hello
create function say_hello as 'com.bigdata.hadoop.hive.GenericUDFHello' using jar 'hdfs://hdpcomprs:9000/libs/hive-1.0-SNAPSHOT.jar';
2、把自定义函数集成到Hive源码中
- 上传文件
把GenericUDFHello.java类上传到如下目录,并修改包名。
$ cd apache-hive-2.3.0-src/ql/src/java/org/apache/hadoop/hive/ql/udf
$ rz
$ vim GenericUDFHello.java
package org.apache.hadoop.hive.ql.udf;
- 代码
package com.bigdata.hadoop.hive;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
/**
* 自定义UDF函数
* 输入:Tom
* 输出:hello:Tom
*/
@Description(
name = "say_hello,ucase",
value = "_FUNC_(str) - Returns str start with hello:",
extended = "Example:\n > SELECT _FUNC_(\'Facebook\') FROM src LIMIT 1;\n \'hello:Facebook\'"
)
public class GenericUDFHello extends UDF {
public String evaluate(final Text s) {
if (s == null) {
return null;
}
return "hello:" + s.toString();
}
public static void main(String[] args) {
System.out.println(new GenericUDFHello().evaluate(new Text("Tom")));
}
}
- 配置FunctionRegistry类
hive 中有一个非常重要的类FunctionRegistry,我们需要将自己自定义的函数在这个类中配置,引入我们自定义函数类GenericUDFHello。
$ cd apache-hive-2.3.0-src/ql/src/java/org/apache/hadoop/hive/ql/exec
$ vim FunctionRegistry.java
import org.apache.hadoop.hive.ql.udf.GenericUDFHello;
注册自定义函数类GenericUDFHello,输入static { 搜索,在静态代码块中注册我们编写的自定义函数,这里面都是hive的所有内置函数,添加如下代码。
system.registerUDF("hello", GenericUDFHello.class, false);
- 编译 Hive 源码
$ cd apache-hive-2.3.0-src
$ mvn clean package -Phadoop-2,dist -DskipTests
-Phadoop-2表示使用的hadoop版本为2,如果为1,则写-Phadoop-1
编译过程中,请耐心等待,编译完成后,hive会生成一个压缩包,解压配置后就可以使用,hive压缩包存放的路径是apache-hive-2.3.0-src/packaging/target。
参考链接:https://blog.csdn.net/HG_Harvey/article/details/77688735