hive注册udf函数
一、 注册udf
1 maven项目pow文件
<properties>
<hive.version>2.1.1-cdh6.1.0</hive.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>${hive.version}</version>
</dependency>
</dependencies>
<!--添加CDH的仓库-->
<repositories>
<repository>
<id>nexus-aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
2 测试类
//注:实现UDF函数的套路是一样的,第一步继承UDF函数,第二步重写evaluate方法
public class HelloUDF extends UDF {
public String evaluate(String input) {
return "Hello:" + input;
}
//测试
public static void main1(String[] args) {
HelloUDF udf = new HelloUDF();
String output = udf.evaluate("测试数据");
System.out.println(output);
}
}
3 打包
mvn package
4 创建永久函数
登录hive
CREATE FUNCTION db.sayHello AS 'com.cd.hive.udfs.udf.HelloUDF' USING JAR 'hdfs:///tmp/lib/hive/hive-udfs-1.0.0-SNAPSHOT.jar';
# 推荐使用hdfs保存jar包,因为放hdfs,整个集群的客户端都可以访问
# 建议把前面的库名带上,意思是该函数作用于某个库,不带的话默认是default库
5 查看函数
# 我是在default库下面建的函数,下面展示查看函数
hive (default)> show functions;
或者
hive (default)> SHOW FUNCTIONS LIKE '*.hello';
# 可以查找到我们的函数
default.sayhello
2 查看mysql中hive元数据库的FUNCS表
SELECT * FROM FUNC_RU;
SELECT * FROM FUNCS;
效果图如下:
查看hive的元数据库,函数相关的表funcs和func_ru
6 删除永久函数
hive (default)> drop FUNCTION sayHello;
7 查看函数说明
hive> describe function abs;
hive> desc function abs;
hive> desc function abs;
OK
abs(x) - returns the absolute value of x
hive> desc function extended abs;
OK
abs(x) - returns the absolute value of x
Example:
> SELECT abs(0) FROM src LIMIT 1;
0
> SELECT abs(-5) FROM src LIMIT 1;
5
二、 踩坑:
注册hive cli 的会话里生效,其他会话无效
我在hive cli里面注册的函数,在cli窗口使用命令,是生效的,如下
并且在元数据库里面也是查到了function信息的(FUNC_RU和FUNCS里面能查到)
但是在其他程序里,比如在beeline里面却没法使用,报错如下
Error: Error while compiling statement: FAILED: SemanticException [Error 10011]: Line 1:7 Invalid function 'sayhello' (state=42000,code=10011)
原因:实例内存数据不一致
hive cli是一个HiveServer客户端实例,beeline是一个HiveServer客户端实例,其他程序也是一个HiveServer客户端实例,而多个HiveServer之间共用的元数据未同步,导致不同HiveServer实例内存数据不一致,造成UDF不生效。
注意:如果多个hiveserver2 实例,如果有问题,可以尝试每个hiveserver2 执行reload functions;我们目前多个实例没有发现这个问题
解决办法:
# 参考官网
LanguageManual DDL - Apache Hive - Apache Software Foundation
需要将新建的UDF信息同步到HiveServer中,登录hive后,执行reload functions 或者reload function(为了兼容以前的版本) 操作即可。
reload functions #在你执行查询之前先执行此操作进行函数元数据同步就ok了
效果图如下: