hive3.1.x 自定义UDF 作者:马育民 • 2021-04-24 13:09 • 阅读:10345 # 解释 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 ``` org.apache.hadoop hadoop-common 3.0.3 org.apache.hadoop hadoop-hdfs 3.0.3 org.apache.hive hive-exec 3.1.2 org.apache.maven.plugins maven-shade-plugin 2.2 package shade *:* META-INF/*.SF META-INF/*.DSA META-INF/*.RSA ``` ### 实现类 **注意:** **包路径** 和 **类名**,下面要用 ``` 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打包,如下图: [](https://www.malaoshi.top/upload/0/0/1GW2MFS9eNuN.png) 一般使用 `original-hive_udf-1.0-SNAPSHOT.jar` 包即可,体积最小的jar,如下图: [](https://www.malaoshi.top/upload/0/0/1GW2MFT1EDUT.png) **注意:**如果报错,就是用 `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` 在配置文件中增加配置 ``` hive.aux.jars.path file:///jarpath/all_new1.jar,file:///jarpath/all_new2.jar ``` # 创建临时函数 ### 临时函数 临时函数只在 **当前 会话中 有效**,在另一个会话中 **不能使用** 如:在 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 ``` 执行结果: [](https://www.malaoshi.top/upload/pic/hive/20220319_112321.png) ### 删除临时函数 ``` 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 ``` 执行结果: [](https://www.malaoshi.top/upload/pic/hive/20220319_112321.png) ### 删除临时函数 ``` drop function toLowerUDF2; ``` 原文出处:http://www.malaoshi.top/show_1IX2HtXRb7bW.html