当Hive的内置函数不能满足需要时,可以通过编写用户自定义函数UDF(User-Defined Functions)进行数据的处理和查询。
按实现方式,UDF分如下分类:
- 普通的UDF,用于操作单个数据行,且产生一个数据行作为输出(一进一出)。
- 用户定义聚集函数UDAF(User-Defined Aggregating Functions),用于接受多个输入数据行,并产生一个输出数据行(多进一出)。
- 用户定义表生成函数UDTF(User-Defined Table-Generating Functions),用于操作单个输入行,产生多个输出行(一进多出)。
按使用方法,UDF有如下分类:
- 临时函数,只能在当前会话使用,重启会话后需要重新创建。
- 永久函数,可以在多个会话中使用,不需要每次创建。
下面以编写一个AddDoublesUDF加密函数为例,说明UDF的编写和使用方法:
AddDoublesUDF主要用来对两个及多个浮点数进行相加。在该样例中可以掌握如何编写和使用UDF函数。
说明:
- 一个普通UDF必须继承自“org.apache.hadoop.hive.ql.exec.UDF”。
- 一个普通UDF必须至少实现一个evaluate()方法,evaluate函数支持重载。
- 开发自定义函数需要在工程中添加hive-exec-3.1.0.jar依赖包,可从hive安装目录下获取。
样例代码
以下为UDF示例代码:
package com.bigdata.hive.example.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class AddDoublesUDF extends UDF {
public Double evaluate(Double... a) {
Double total = 0.0;
// 处理逻辑部分.
for (int i = 0; i < a.length; i++)
if (a[i] != null)
total += a[i];
return total;
}
}
//注意:打包的时候一定要有main方法(即使没有内容)
如何使用
1、把以上程序打包成AddDoublesUDF.jar,并上传到HDFS指定目录下(如“/user/hive_examples_jars/”)且创建函数的用户与使用函数的用户有该文件的可读权限。
示例语句:
hdfs dfs -put ./hive_examples_jars /user/hive_examples_jars //上传jar文件
hdfs dfs -chmod 777 /user/hive_examples_jars //给文件777权限
2、在Hive Server中定义该函数,以下语句用于创建永久性函数:
CREATE FUNCTION addDoubles AS 'com.bigdata.hive.example.udf.AddDoublesUDF' using jar '
hdfs://Route/user/hive_examples_jars/AddDoublesUDF.jar';
注:其中addDoubles 是该函数的别名,用于SELECT查询中使用。'com.bigdata.hive.example.udf.AddDoublesUDF' 是包名+类名。
以下语句用于创建临时函数:
CREATE TEMPORARY FUNCTION addDoubles AS 'com.huawei.bigdata.hive.example.udf.AddDoublesUDF' using jar '
hdfs://Route/user/hive_examples_jars/AddDoublesUDF.jar';
- addDoubles 是该函数的别名,用于SELECT查询中使用。
- 关键字 TEMPORARY 说明该函数只在当前这个Hive Server的会话过程中定义使用。
3、在Hive Server中使用该函数,执行SQL语句:
SELECT addDoubles(1,2,3);
说明:
若重新连接客户端再使用函数出现[Error 10011]的错误,可执行reload function;命令后再使用该函数。
4、在Hive Server中删除该函数,执行SQL语句:
DROP FUNCTION addDoubles;