hive UDF注册以及编写

背景

公司有个业务需求,需要对一些算子进行实现,写UDF,刚开始打算用sql 实现,但是考虑到算子可能嵌套等复杂情况,遂用udf 去做。

UDF编写

1、UDF数据类型

这里先讲一下UDF的数据类型,刚开始我写UDF的时候使用java 中的bigDecimal 等数据类型发现是不行的。然后我开始找hive 相关的数据类型。发现网上写的也少,然后我在想hive内置的函数为什么支持decimal,long的数据类型呢。我就在github中的hive的源码里全局查找hive的内置函数,为了方便查找,我找了个复杂一些的内置函数查找。然后找到了
https://github.com/apache/hive/blob/91a92e323a29a49b5ad3b860b9523f347b6b8d4c/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
这一个注册函数的类。然后我随便选取了 ceil 这个函数,看看他是怎么对数据进行的处理,然后发现了hive支持的数据类型,参照下面源代码

public final class GenericUDFCeil extends GenericUDFFloorCeilBase {

  public GenericUDFCeil() {
    super();
    opDisplayName = "ceil";
  }

  @Override
  protected LongWritable evaluate(DoubleWritable input) {
    longWritable.set((long) Math.ceil(input.get()));
    return longWritable;
  }

  @Override
  protected HiveDecimalWritable evaluate(HiveDecimalWritable input) {
    decimalWritable.set(input);
    decimalWritable.mutateSetScale(0, HiveDecimal.ROUND_CEILING);
    return decimalWritable;
  }

这样就迎刃而解了。编写UDF 的数据类型是
HiveDecimalWritable,DoubleWritable,LongWritable 等 岔开一句 我发现 Long 和String 也是支持的。

2、编写UDF

只要集成UDF类然后重写evaluate 方法就好了,这块没什么好说的。
唯一一点就是如果想要接入不同的参数,重载方法就好,像我上面的ceil内置函数的源码一样
如下图所示

public class DataMaxUdf extends UDF {
    public Integer evaluate(Integer a,Integer b) {
        if (a == null || b==null) { return null; }
        return a>b?a:b;
    }
}

UDF注册

注册UDF 分为临时注册和永久注册,参考资料https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateFunction

1、 临时函数

临时函数以session生命周期(比如你打开关闭 hive cli 或者beeline)
示例代码(在shell里)

add jar /home/hadoop/zgh/hiveudf-1.0-SNAPSHOT.jar;
create temporary function ceshi as 'com.example.udf.DataMaxUdf';

这样即可注册一个临时函数了。

2、永久注册

将其打包上传到hdfs 的目录下,在hive cli 中执行

create function zgh.data_max as 'com.example.udf.DataMaxUdf' using jar 'hdfs:///user/zgh/hiveudf.jar';

这样就在zgh databases 下面创建了一个 data_max的自定义函数。当每次访问函数时,他会默认去hdfs 加载当前函数。

注意

1

、比如传入的参数需要时bigInt格式的话,这边就需要传入Long 类型的格式,,比如这种,Integer类型是不支持bigInt的

public class DataMinUdf extends UDF {

    public Long evaluate(Long a, Long b) {
        if (a == null || b==null) { return null; }
        return a>b?b:a;
    }
}

2

、hiverserver2 访问的时候发现注册的udf 访问不到
hive在1.2版本以后,使用jdbc 访问hiveserver2 和hive cli 将有可能访问不到udf。官网解释如下

creating permanent functions in one Hive CLI session may not be reflected in HiveServer2 or other Hive CLI sessions,
 if they were started before the function was created. 
Issuing RELOAD FUNCTIONS within a HiveServer2 or HiveCLI session will allow it to pick up any changes to the permanent functions that may have been done by a different HiveCLI session.
Due to backward compatibility reasons RELOAD FUNCTION; is also accepted.

所以,在访问udf的时候,需要先执行

RELOAD FUNCTIONS

来获取udf的更新情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值