hive3.1.x 自定义UDF

解释

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;