【impala】Impala 加载Hive的UDF函数,并设置为持久化persistent

993 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、前言:

最近在使用impala组件时,发现有些在hive里有而impala里没有的函数,如 在Hive中有一个UDF为get_json_object,用于解析Json,但是Imapla中没有类似的函数。

于是进行了一些调研。

impala 的 UDF函数是支持使用hive 的 UDF函数的。因为 Impala 和 Hive 共享相同的 Metastore 数据库。

所以决定想将hive的 UDF 函数添加到impala 中。其中参考了一些网上的文章,最终实现了我的需求。这里整理并记录一下。

二、实践:

环境信息:

  • CDH : 5.13
  • impala : 2.10.0
  • hive : 1.1

Impala的UDF有两种:

  • Native Imapal UDF:使用C++开发的,性能极高,官方性能测试比第二种高出将近10倍

  • Hive的UDF:是Hive中的UDF,直接加载到Impala中,优点是不需要任何改动,完全跟Hive中用法相同。

这里选择方法二,来添加Impala的函数。

1. hive 函数位置:

该function所在的jar包是在/opt/cloudera/parcels/CDH/lib/hive/lib/hive-exec-1.1.0-cdh5.13.3.jar

我这里是使用的CDH5.13版本,大家根据自己的环境选择对应的jar包。包名是类似的。

2. 查看下该包有哪些函数

jar tf hive-exec-1.1.0-cdh5.13.3.jar |grep UDFJson

函数如下:

org/apache/hadoop/hive/ql/udf/UDFJson$AddingList.class
org/apache/hadoop/hive/ql/udf/UDFJson$HashCache.class
org/apache/hadoop/hive/ql/udf/UDFJson$1.class
org/apache/hadoop/hive/ql/udf/UDFJson.class

3. 把jar包上传到hdfs的目录中,如下:

hdfs dfs -put hive-exec-1.1.0-cdh5.13.0.jar /udf/hive-exec.jar

4. 在Impala Shell中创建function

使用Impala Shell中创建function,其中Symbol指向类名称:https://github.com/apache/hive/blob/branch-0.14/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFJson.java

创建impala 函数语句:

create function if not exists get_json_object(String,String) returns String location "/udf/hive-exec.jar" SYMBOL="org.apache.hadoop.hive.ql.udf.UDFJson";

5. 查看函数

show functions;

查看结果:

[impala-jdbc.com:21000] > show functions;
Query: show functions+-------------+---------------------------------+-------------+---------------+
| return type | signature                       | binary type | is persistent |
+-------------+---------------------------------+-------------+---------------+
| STRING      | get_json_object(STRING, STRING) | JAVA        | false         |
+-------------+---------------------------------+-------------+---------------+
Fetched 1 row(s) in 0.41s
[impala-jdbc.com:21000] > 

6. 测试使用:

测试一下函数时候能正常提供服务:

[impala-jdbc.rong360.com:21000] > select get_json_object('{"name":"zhangsan"}', '$.name');
Query: select get_json_object('{"name":"zhangsan"}', '$.name')
Query submitted at: 2021-10-14 20:04:02 (Coordinator: http://dx-hadoop56.dx:25000)
Query progress can be monitored at: http://dx-hadoop56.dx:25000/query_plan?query_id=c14a699e5fa19356:3a7ba4d000000000
+----------------------------------------------------------+
| op_test.get_json_object('{"name":"zhangsan"}', '$.name') |
+----------------------------------------------------------+
| zhangsan                                                 |
+----------------------------------------------------------+
Fetched 1 row(s) in 0.01s

三、持久化:

此时,我们已经将HIVE的函数添加到了Impala 中,但是可能有人注意到这个函数的持久化状态为false

那么就意味着,当我们的impala服务重启了,这个临时函数就消失了。

怎样让这个临时函数变成持久化函数。

  • 创建C++类型的持久化函数
CREATE FUNCTION [IF NOT EXISTS] [db_name.]function_name([arg_type[, arg_type...])
  RETURNS return_type
  LOCATION 'hdfs_path_to_dot_so'
  SYMBOL='symbol_name'

在这里插入图片描述

  • 创建HIVE类型的持久化函数
CREATE FUNCTION [IF NOT EXISTS] [db_name.]function_name
  LOCATION 'hdfs_path_to_jar'
  SYMBOL='class_name'

在这里插入图片描述

这个创建持久化函数的语法对版本是有限制的需要大于 CDH 5.7 / Impala 2.5 。大家可以根据impala 文档来进行查看自己的版本创建持久函数的语法。

那么我们根据JAVA的持久化函数来编写我们的持久化函数。

临时函数如下:

create function if not exists get_json_object(String,String) 
returns String 
location "/udf/hive-exec.jar" 
SYMBOL="org.apache.hadoop.hive.ql.udf.UDFJson";

持久化函数如下:

create FUNCTION IF NOT EXISTS default.get_json_object
location "/udf/hive-exec.jar" 
SYMBOL="org.apache.hadoop.hive.ql.udf.UDFJson";

注意:这里需要注意的是java持久化编写的语法,我看有的文章是让注意换行,导致我走了不少弯路,这里需要注意的是跟换行没有任何关系,大家切记!!

补充:

  1. 删除函数
drop function default.get_json_object(STRING, STRING);

参考文章如下:

  • https://docs.cloudera.com/documentation/enterprise/5-13-x/topics/impala_create_function.html#create_function
  • https://docs.cloudera.com/documentation/enterprise/5-13-x/topics/impala_udf.html#udf_limits
  • https://www.pianshen.com/article/7441552489/
  • https://www.cnblogs.com/qizhelongdeyang/p/9240402.html