Hive用户自定义函数
一、前言
1.1、简介
Hive 自带了一些函数,比如:max/min 等,但是针对一些特殊业务,可能无法很好使用内置函数完成,自己可以通过自定义 UDF 来方便的扩展。当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。
根据用户自定义函数类别分为以下三种:
(1)UDF(User-Defined-Function)
一进一出
(2)UDAF(User-Defined Aggregation Function)
多进一出,聚合函数,类似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions)
一进多出,表生成函数,如 lateral view explore()
1.2、准备工作
创建一个 maven 项目,添加依赖
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.14.2</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>1.1.0-cdh5.14.2</version>
</dependency>
</dependencies>
添加打包插件:
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
二、分类
2.1、UDF
2.1.1、编程步骤
UDF 必须要有返回类型,可以返回 null,但是返回类型不能为 void
- 继承 org.apache.hadoop.hive.ql.UDF
- 需要实现 evaluate 函数;evaluate 函数支持重载
- 在 hive 的命令行窗口创建函数
a)添加 jar
add jar linux_jar_path;
b)创建 function
create [temporary] function [dbname.]function_name AS class_name; - 调用函数
2.1.2、案例
此处编写一个函数,可以将输入的字符串转换成小写字母
(1)创建一个类
package cn.kgc.hive.func;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class MyUDF extends UDF {
//重写evaluate方法
public Text evaluate(Text s){
if (s==null){
return null;
}
//把字符串s转换成小写字母
return new Text(s.toString().toLowerCase());
}
}
(2)打成jar包
(3)重命名,放到linux本地目录
(4)将 jar 包添加到 hive 的 classpath
0: jdbc:hive2://single:10000> add jar /root/jar/low.jar;
No rows affected (0.029 seconds)
(5)创建临时函数与开发好的 java class 关联
0: jdbc:hive2://single:10000> create temporary function myLow as "cn.kgc.hive.func.MyUDF";
INFO : Compiling command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a): create temporary function myLow as "cn.kgc.hive.func.MyUDF"
INFO : Semantic Analysis Completed
INFO : Returning Hive schema: Schema(fieldSchemas:null, properties:null)
INFO : Completed compiling command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a); Time taken: 0.001 seconds
INFO : Concurrency mode is disabled, not creating a lock manager
INFO : Executing command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a): create temporary function myLow as "cn.kgc.hive.func.MyUDF"
INFO : Starting task [Stage-0:FUNC] in serial mode
INFO : Completed executing command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a); Time taken: 0.001 seconds
INFO : OK
No rows affected (0.015 seconds)
(6)使用自定义函数
2.2、UDAF
2.3、UDTF
三、扩展
3.1、添加jar包方法
(1)该方法每次启动 Hive 的时候都要重新加入,退出 hive 就会失效,在 hive 下执行
add jar /home/hadoop/DefTextInputFormat.jar;
Added [/home/hdfs/DefTextInputFormat.jar] to class path
Added resources: [/home/hdfs/DefTextInputFormat.jar]
(2)hive-site.xml 文件配置 hive.aux.jars.path
该方法不需要每次启动 Hive 执行命令加入,需要配置文件
<property>
<name>hive.aux.jars.path</name>
<value>file:///home/hadoop/DefTextInputFormat.jar,file:///jarpath/test.jar</value>
</property>
(3)创建文件夹
根目录${HIVE_HOME}下创建文件夹 auxlib,然后将自定义 jar文件放入该文件夹中。
该方法方便快捷,不过对于客户端操作环境就不能执行
3.2、自定义临时/永久函数
(1)临时函数——仅对当前 session(黑窗口)有效
一旦退出 HIVE 客户端,自定义临时函数即被删除。
- 添加 jar 包
hive> add jar /root/jar/low.jar; - 创建自定义临时函数
hive> create temporary function myLow as “cn.kgc.hive.func.MyUDF”; - 使用自定义临时函数
hive> select myLow(“aBcDeF”); - 这里我们切换数据库依然可以正常使用
- 删除自定义临时函数
hive> drop temporary function myLow;
(2)永久函数
- 先上传到 HDFS
[root@single jar]# hdfs dfs -put low.jar /UDF
- 创建永久函数
create function myLow as 'cn.kgc.hive.func.MyUDF' using jar 'hdfs:///UDF/low.jar'
- 与自定义临时函数不同,使用永久函数只能在当前数据库
- 测试
- 切换数据库测试
0: jdbc:hive2://single:10000> use demo;
0: jdbc:hive2://single:10000> select myLow('aB');
Error: Error while compiling statement: FAILED: SemanticException [Error 10011]: Line 1:7 Invalid function 'myLow' (state=42000,code=10011)
- 删除自定义永久函数
0: jdbc:hive2://single:10000> drop function myLow;