UDF?UDAF?UDTF?看了你就明白!

Hive用户自定义函数

一、前言

1.1、简介

Hive 自带了一些函数,比如:max/min 等,但是针对一些特殊业务,可能无法很好使用内置函数完成,自己可以通过自定义 UDF 来方便的扩展。当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。

根据用户自定义函数类别分为以下三种:

(1)UDF(User-Defined-Function)
一进一出
(2)UDAF(User-Defined Aggregation Function)
多进一出,聚合函数,类似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions)
一进多出,表生成函数,如 lateral view explore()

1.2、准备工作

创建一个 maven 项目,添加依赖

  <dependencies>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>2.6.0-cdh5.14.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-exec</artifactId>
      <version>1.1.0-cdh5.14.2</version>
    </dependency>
  </dependencies>

添加打包插件:

<build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
</build>

二、分类

2.1、UDF

2.1.1、编程步骤

UDF 必须要有返回类型,可以返回 null,但是返回类型不能为 void

  1. 继承 org.apache.hadoop.hive.ql.UDF
  2. 需要实现 evaluate 函数;evaluate 函数支持重载
  3. 在 hive 的命令行窗口创建函数
    a)添加 jar
    add jar linux_jar_path;
    b)创建 function
    create [temporary] function [dbname.]function_name AS class_name;
  4. 调用函数

2.1.2、案例

此处编写一个函数,可以将输入的字符串转换成小写字母
(1)创建一个类

package cn.kgc.hive.func;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public class MyUDF extends UDF {
    //重写evaluate方法
    public Text evaluate(Text s){
        if (s==null){
            return null;
        }
        //把字符串s转换成小写字母
        return new Text(s.toString().toLowerCase());
    }
}

(2)打成jar包
UDF?UDAF?UDTF?看了你就明白!
(3)重命名,放到linux本地目录
UDF?UDAF?UDTF?看了你就明白!
UDF?UDAF?UDTF?看了你就明白!
(4)将 jar 包添加到 hive 的 classpath

0: jdbc:hive2://single:10000> add jar /root/jar/low.jar;
No rows affected (0.029 seconds)

(5)创建临时函数与开发好的 java class 关联

0: jdbc:hive2://single:10000> create temporary function myLow as "cn.kgc.hive.func.MyUDF";
INFO  : Compiling command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a): create temporary function myLow as "cn.kgc.hive.func.MyUDF"
INFO  : Semantic Analysis Completed
INFO  : Returning Hive schema: Schema(fieldSchemas:null, properties:null)
INFO  : Completed compiling command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a); Time taken: 0.001 seconds
INFO  : Concurrency mode is disabled, not creating a lock manager
INFO  : Executing command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a): create temporary function myLow as "cn.kgc.hive.func.MyUDF"
INFO  : Starting task [Stage-0:FUNC] in serial mode
INFO  : Completed executing command(queryId=root_20201215173535_6269f4db-af00-4053-9c3a-b0e27c03157a); Time taken: 0.001 seconds
INFO  : OK
No rows affected (0.015 seconds)

(6)使用自定义函数
UDF?UDAF?UDTF?看了你就明白!


2.2、UDAF


2.3、UDTF


三、扩展

3.1、添加jar包方法

(1)该方法每次启动 Hive 的时候都要重新加入,退出 hive 就会失效,在 hive 下执行

add jar /home/hadoop/DefTextInputFormat.jar;
Added [/home/hdfs/DefTextInputFormat.jar] to class path
Added resources: [/home/hdfs/DefTextInputFormat.jar]

(2)hive-site.xml 文件配置 hive.aux.jars.path

该方法不需要每次启动 Hive 执行命令加入,需要配置文件

<property>
<name>hive.aux.jars.path</name>
<value>file:///home/hadoop/DefTextInputFormat.jar,file:///jarpath/test.jar</value>
</property>

(3)创建文件夹

根目录${HIVE_HOME}下创建文件夹 auxlib,然后将自定义 jar文件放入该文件夹中。
该方法方便快捷,不过对于客户端操作环境就不能执行


3.2、自定义临时/永久函数

(1)临时函数——仅对当前 session(黑窗口)有效

一旦退出 HIVE 客户端,自定义临时函数即被删除。

  1. 添加 jar 包
    hive> add jar /root/jar/low.jar;
  2. 创建自定义临时函数
    hive> create temporary function myLow as “cn.kgc.hive.func.MyUDF”;
  3. 使用自定义临时函数
    hive> select myLow(“aBcDeF”);
  4. 这里我们切换数据库依然可以正常使用
  5. 删除自定义临时函数
    hive> drop temporary function myLow;

(2)永久函数

  1. 先上传到 HDFS
[root@single jar]# hdfs dfs -put low.jar /UDF
  1. 创建永久函数
create function myLow as 'cn.kgc.hive.func.MyUDF' using jar 'hdfs:///UDF/low.jar'
  1. 与自定义临时函数不同,使用永久函数只能在当前数据库
  2. 测试
    UDF?UDAF?UDTF?看了你就明白!
  3. 切换数据库测试
0: jdbc:hive2://single:10000> use demo;
0: jdbc:hive2://single:10000> select myLow('aB');
Error: Error while compiling statement: FAILED: SemanticException [Error 10011]: Line 1:7 Invalid function 'myLow' (state=42000,code=10011)
  1. 删除自定义永久函数
0: jdbc:hive2://single:10000> drop function myLow;
上一篇:hive 窗口函数简介(udf\udaf\udtf)


下一篇:第四章-2-编程处理数据(pandas模块)(-)