UDF 主要适用于,用户需要的分析能力 Doris 并不具备的场景。用户可以自行根据自己的需求,实现自定义的函数,并且通过 UDF 框架注册到 Doris 中,来扩展 Doris 的能力,并解决用户分析需求。
UDF 能满足的分析需求主要分为两种(本文中的 UDF 指的是二者的统称):
正式推出Java UDF 之前,Apache Doris提供了原生 UDF即C++ UDF 。由于是使用 C++ 来编写的,执行效率高、速度更快,但是在实际使用中也会存在一些问题:
针对以上问题,Apache Doris 在1.2.0版本中正式推出全新的Java UDF ,让用户可以更便捷高效地开发和迁移UDF。
众所周知,Doris的FE主要由JAVA编写、而BE是由C++编写。因此,如果需要C++编写的BE与JAVA UDF联动,那么必然需要借助网络通信或JNI(Java Native Interface):
JNI调用需要进行Java与本地代码之间的切换和数据转换,这也会带来一定的性能开销,如果频繁的JNI调用还可能会对应用的性能产生不利影响。那么Doris该如何设计 Java UDF 呢?
下面,就来一起体验下Apache Doris 的 Java UDF吧。
直接IntelliJ IDEA:
Java UDF 使用起来非常简单。只需要按规范开发完并通过mvn打成jar包后,在 Apache Doris 内注册一下,即可调用 jar 包来实现 UDF 逻辑:
仅补齐dependencies和build部分。
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.5</version>
<exclusions>
<exclusion>
<groupId>org.pentaho</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>doris_java_udf</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>org.apache.doris.udf.AddOne</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.apache.doris.udf.AddOne</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
直接使用官方的demo:
https://github.com/apache/doris/blob/master/samples/doris-demo/java-udf-demo/src/main/java/org/apache/doris/udf/AddOne.java
package org.apache.doris.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class AddOne extends UDF {
public Integer evaluate(Integer value) {
return value == null? null: value + 1;
}
}
先clean清理target。
再package打新包。
打好的jar包(即doris_java_udf.jar,不需要传依赖jar包),可以以两种方式存放:
本文选择本地路径的方式演练:
-- udf
-- 查看
show full functions;
-- 删除
DROP FUNCTION add_one(int);
-- 创建
-- 函数名可自定义
CREATE FUNCTION add_one(int) RETURNS int PROPERTIES (
-- 文件路径,可本地或http
"file"="file:///udf/doris_java_udf.jar",
-- extends UDF 的类名
"symbol"="org.apache.doris.udf.AddOne",
-- 可选,如果在计算中对出现的NULL值有特殊处理,确定结果中不会返回NULL,可以设为false
"always_nullable"="true",
-- 默认为 Native,使用 Java UDF时传 JAVA_UDF
"type"="JAVA_UDF"
)
-- 测试,在传参基础上+1,如果非数字或者null则返回null
select add_one('0');
虽然JAVA UDF整起来非常顺畅方便,但实际生产使用中有如下一些官方提醒:
Java UDF相对1.2之前的C++ UDF而言,使用起来会更加便捷高效,而且更利于Hive/Spark的UDF jar包迁移,并且Doris团队对其底层实现流程进行了一系列性能优化,面面俱到。各位看官大可放心使用!