解释
UDF,User-Defined Functions,用户定义的hive函数。
hive自带的函数并不能完全满足业务需求,这时就需要我们自定义函数了
UDF 特点:one to one,进来一个出去一个,是row级别操作,如:upper、substr函数
实现
官网:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateFunction
https://cwiki.apache.org/confluence/display/Hive/HivePlugins
创建maven工程
略
pom.xml
<dependencies>
<!--添加Hadoop的依赖-->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.0.3</version>
</dependency>
<!--添加hive依赖-->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
<build>
<!-- 将依赖jar包都放进去,防止缺失某个jar包 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<!-- 排除以下文件,防止程序启动时,校验错误 -->
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
实现类
注意: 包路径 和 类名,下面要用
package myhive;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class LowerUDF extends UDF {
public Text evaluate(Text str){
if(null == str){
return null ;
}
return new Text(str.toString().toLowerCase()) ;
}
public static void main(String[] args) {
System.out.println(new LowerUDF().evaluate(new Text("ABC")));
}
}
打包
maven打包,如下图:
一般使用 original-hive_udf-1.0-SNAPSHOT.jar 包即可,体积最小的jar,如下图:
注意:如果报错,就是用 hive_udf-1.0-SNAPSHOT.jar 体积大的jar包,包含所有的依赖
添加jar包
需要添加 jar 包才能使用,有下面3种方式
添加jar包-方式一(推荐)
在 $HIVE_HOME 中创建文件夹 auxlib,然后将jar包放入该文件夹中
- 需要重启 hiverserver2 服务
- hive shell 和 hive客户端 不需要 执行加载 jar包命令
添加jar包-方式二
- 可以将 jar 包上传到任意位置
- Hive Shell或hive客户端:需要执行命令才能加载 jar
- Hive Server:无效
上传到 hadoop1
将 jar 包上传到 hadoop1 的 /program/myjar/ 目录
添加jar包命令
在 hive环境中执行下面命令:
add jar /program/myjar/original-hive_udf-1.0-SNAPSHOT.jar;
注意: 重启 hive 环境后,需要重新添加
查看添加的jar包
list jar
添加jar包-方式三-修改文件(不推荐)
方式一:hive-env.sh
通过 ${HIVE_HOME}/conf/hive-env.sh 下配置:
export HIVE_AUX_JARS_PATH=/home/hadoop/apache/hive-0.13.1/lib/mysql-connector-java-5.1.7-bin.jar
本地文件路径
方式二:hive-site.xml
通过设置配置文件 hive-site.xml
在配置文件中增加配置
<property>
<name>hive.aux.jars.path</name>
<value>file:///jarpath/all_new1.jar,file:///jarpath/all_new2.jar</value>
</property>
创建临时函数
临时函数
临时函数只在 当前 会话中 有效,在另一个会话中 不能使用
如:在 dbeaver 中,在当前窗口中创建 临时函数,就只能在 当前窗口中使用,在另一个窗口中,会报错,如下:
SQL 错误 [10011] [42000]: Error while compiling statement: FAILED: SemanticException [Error 10011]: Invalid function toLowerUDF
语法
create temporary function 函数名 as '类的全路径';
例子:
create temporary function toLowerUDF as 'myhive.LowerUDF';
使用
select ename,toLowerUDF(ename) from emp
执行结果:
删除临时函数
drop temporary function toLowerUDF;
创建永久(普通)函数
永久(普通)函数
可以在所有的会话中使用
如:在 dbeaver 中,在当前窗口中创建 临时函数,即能在 当前窗口中使用,也能在另一个窗口中使用
必须放 HDFS(推荐)
若为 YARN 集群,各节点的 MapReduce 执行 UDF 时,会从指定路径拉取 JAR 包:
- 本地 JAR 需在所有
NodeManager节点的相同路径下放一份(维护成本高) - 存放到
HDFS上,JAR 无需同步,所有节点均可访问(推荐)
上传到 hadoop1
将 original-hive_udf-1.0-SNAPSHOT.jar 包上传到 hadoop1 的 /program/myjar/ 目录
上传到 HDFS
在 HDFS 上创建目录:
hadoop fs -mkdir /hive/udf
hadoop fs -put /program/myjar/original-hive_udf-1.0-SNAPSHOT.jar /hive/udf
语法
create function 函数名 as '类的全路径' using jar 'hdfs路径';
例子:
create function toLowerUDF2 as 'myhive.LowerUDF' using jar 'hdfs:/hive/udf/original-hive_udf-1.0-SNAPSHOT.jar';
其他 hive shell 或 hive客户端重启后,即可使用
使用
select ename,toLowerUDF2(ename) from emp
执行结果:
删除临时函数
drop function toLowerUDF2;


