Hive自定义函数详解

虽然hive中为我们提供了很多的内置函数,但是在实际工作中,有些情况下hive提供的内置函数无法满足我们的需求,就需要我们自己来手动编写,所以就有了自定义函数 UDF。

一、自定义函数分类

UDF分为三种,分别如下:

1、UDF(User-Defined-Function),一进一出(输入一行,输出一行),比如:upper()、lower()等。

UDF编程模型:

  • 继承 org.apache.hadoop.hive.ql.exec.UDF
  • 实现 evaluate() 方法

2、UDAF(User-Defined Aggregation Funcation),多进一出(输入多行,输出一行),比如:avg()、sum()等。

UDAF编程模型:

  • 继承 org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver;
  • 实现 evaluate() 方法
  • 编写静态内部类(函数的计算逻辑),继承GenericUDAFEvaluator,必须重写如下方法

3、UDTF(User-Defined Table-Generating Functions),一进多出(输入一行,输出多行),比如:collect_set()、collect_list()等。

UDAF编程模型:

  • 继承 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
  • 实现三个方法 initialize()、process()、close()

官方文档:https://cwiki.apache.org/confluence/display/Hive/HivePlugins

使用自定义函数需要引入hive-exec的依赖

<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>2.3.0</version>
</dependency>

二、自定义函数使用方法

1、通过上传到hdfs使用

  • 上传jar到hdfs
$ hadoop fs -put hive-1.0-SNAPSHOT.jar /libs
  • 创建函数 say_hello
create function say_hello as 'com.bigdata.hadoop.hive.GenericUDFHello' using jar 'hdfs://hdpcomprs:9000/libs/hive-1.0-SNAPSHOT.jar';

2、把自定义函数集成到Hive源码中

  • 上传文件

把GenericUDFHello.java类上传到如下目录,并修改包名。

$ cd apache-hive-2.3.0-src/ql/src/java/org/apache/hadoop/hive/ql/udf
$ rz
$ vim GenericUDFHello.java
package org.apache.hadoop.hive.ql.udf;
  • 代码
package com.bigdata.hadoop.hive;

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

/**
 * 自定义UDF函数
 * 输入:Tom
 * 输出:hello:Tom
 */
@Description(
        name = "say_hello,ucase",
        value = "_FUNC_(str) - Returns str start with hello:",
        extended = "Example:\n  > SELECT _FUNC_(\'Facebook\') FROM src LIMIT 1;\n  \'hello:Facebook\'"
)
public class GenericUDFHello extends UDF {

    public String evaluate(final Text s) {
        if (s == null) {
            return null;
        }
        return "hello:" + s.toString();
    }

    public static void main(String[] args) {
        System.out.println(new GenericUDFHello().evaluate(new Text("Tom")));
    }
}
  • 配置FunctionRegistry类
    hive 中有一个非常重要的类FunctionRegistry,我们需要将自己自定义的函数在这个类中配置,引入我们自定义函数类GenericUDFHello。
$ cd apache-hive-2.3.0-src/ql/src/java/org/apache/hadoop/hive/ql/exec
$ vim FunctionRegistry.java
import org.apache.hadoop.hive.ql.udf.GenericUDFHello;

注册自定义函数类GenericUDFHello,输入static { 搜索,在静态代码块中注册我们编写的自定义函数,这里面都是hive的所有内置函数,添加如下代码。

system.registerUDF("hello", GenericUDFHello.class, false);
  • 编译 Hive 源码
$ cd apache-hive-2.3.0-src
$ mvn clean package -Phadoop-2,dist -DskipTests
-Phadoop-2表示使用的hadoop版本为2,如果为1,则写-Phadoop-1

编译过程中,请耐心等待,编译完成后,hive会生成一个压缩包,解压配置后就可以使用,hive压缩包存放的路径是apache-hive-2.3.0-src/packaging/target。

参考链接:https://blog.csdn.net/HG_Harvey/article/details/77688735

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容