开发和应用Hive UDF
用户可以自定义一些函数,用于扩展SQL以满足个性化的需求,这类函数称为UDF。
本章节主要介绍开发和应用Hive UDF的具体步骤。
需要基于JDK17.0.4及以上版本开发。
开发Hive UDF项目
本样例实现一个Hive UDF,说明见下表。
名称 |
说明 |
---|---|
AutoAddOne |
对输入的数字加1后返回 |
- 一个普通Hive UDF必须继承自“org.apache.hadoop.hive.ql.exec.UDF”。
- 一个普通Hive UDF必须至少实现一个evaluate()方法,evaluate方法支持重载。
- 当前只支持以下数据类型:
- boolean、byte、short、int、long、float、double
- Boolean、Byte、Short、Int、Long、Float、Double
- List、Map
目前暂不支持除以上类型外的更复杂数据类型的UDF、UDAF和UDTF。
- 当前只支持入参数量小于或等于5个的Hive UDF,大于5个入参的Hive UDF将无法被注册。
- 如果Hive UDF入参为null,系统调用Hive UDF将直接返回null,不会解析null作为入参的Hive UDF逻辑,这可能导致处理null值的Hive UDF执行结果与Hive执行结果不一致。
- 需要在maven工程中添加hive-exec-3.1.1的依赖,可从Hive服务安装目录下获取。
- (可选)若用户存在Hive UDF依赖的配置文件,建议将其作为资源文件放在resources目录下,即可打包到Hive UDF函数包中。
- 创建Maven项目,“groupId”配置“com.test.udf”,“artifactId”配置“udf-test”。这个两个值可根据实际情况自定义。
- 修改“pom.xml”文件如下:
<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"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.udf</groupId> <artifactId>udf-test</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>3.1.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/</outputDirectory> <resources> <resource> <directory>src/main/resources/</directory> <filtering>false</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
- 创建Hive UDF实现类。
import org.apache.hadoop.hive.ql.exec.UDF; /** * AutoAddOne * * @since 2020-08-24 */ public class AutoAddOne extends UDF { public int evaluate(int data) { return data + 1; } }
- 打包Maven项目,target目录下的udf-test-0.0.1-SNAPSHOT.jar文件即为Hive UDF函数包。
需要将所有依赖文件都打包到jar包里。
配置Hive UDF
用户通过在配置文件“udf.properties”中添加注册信息来注册Hive UDF,需按“函数名称 类路径”格式添加每一行内容:
以“udf.properties” 为例,已明确要注册的四个Hive UDF:
booleanudf io.hetu.core.hive.dynamicfunctions.examples.udf.BooleanUDF shortudf io.hetu.core.hive.dynamicfunctions.examples.udf.ShortUDF byteudf io.hetu.core.hive.dynamicfunctions.examples.udf.ByteUDF intudf io.hetu.core.hive.dynamicfunctions.examples.udf.IntUDF
- 如果用户添加的Hive UDF注册信息有误,比如错误的格式或者不存在的类路径,系统将忽略这些错误的注册信息,并打印相应日志。
- 如果用户注册重复的Hive UDF,系统将只注册一次,并忽略重复的注册。
- 如果用户注册的Hive UDF与系统内部注册的相同,系统将会发生异常并无法正常启动。解决该异常需要用户删除对应的Hive UDF注册信息。
部署Hive UDF
要在HetuEngine中使用Hive UDF,需要用户将相应的UDF函数包、“udf.properties”、UDF依赖的配置文件上传到指定HDFS路径,例如“/user/hetuserver/udf/”,并重启HetuEngine计算实例。
- 创建“/user/hetuserver/udf/data/externalFunctions”文件夹,将“udf.properties”放在“/user/hetuserver/udf”,将UDF函数包放在“/user/hetuserver/udf/data/externalFunctions”,将UDF依赖的配置文件放在“/user/hetuserver/udf/data”。
- 使用HDFS的页面上传。
- 使用HetuEngine用户登录FusionInsight Manager,选择“集群 > 服务 > HDFS”,进入HDFS服务页面。
- 在概览页签下的“基本信息”区域,单击“NameNode WebUI”后的链接,进入NameNode WebUI界面。
- 选择“/user/hetuserver/udf/data/externalFunctions”。 ,单击创建
- 进入“/user/hetuserver/udf”,单击上传“udf.properties”。
- 进入“/user/hetuserver/udf/data/”,单击上传UDF依赖的配置文件。
- 进入“/user/hetuserver/udf/data/externalFunctions”,单击上传UDF函数包。
- 使用HDFS命令行上传。
- 登录HDFS服务客户端所在节点,切换到客户端安装目录,例如“/opt/client”。
cd /opt/client
- 执行以下命令配置环境变量。
- 如果集群为安全模式,执行以下命令进行用户认证。普通模式集群无需执行用户认证。
根据回显提示输入密码。
- 执行如下命令创建目录,并将已准备好相应的UDF函数包、“udf.properties”、UDF依赖的配置文件上传到目录路径。
hdfs dfs -mkdir /user/hetuserver/udf/data/externalFunctions
hdfs dfs -put ./UDF依赖的配置文件 /user/hetuserver/udf/data
hdfs dfs -put ./udf.properties /user/hetuserver/udf
hdfs dfs -put ./UDF函数包 /user/hetuserver/udf/data/externalFunctions
- 登录HDFS服务客户端所在节点,切换到客户端安装目录,例如“/opt/client”。
- 使用HDFS的页面上传。
- 重启HetuEngine计算实例。
使用Hive UDF
使用客户端访问:
- 进入HetuEngine客户端,请参考使用HetuEngine客户端。
- 执行如下命令应用Hive UDF:
select AutoAddOne(1); _col0 ------- 2 (1 row)