Blink 开发Java自定义函数(UDX)
概述
注意事项
- UDX函数仅适用于Blink,对开源Flink暂不适用。
- 为了避免JAR依赖冲突,您需要注意以下几点:
- 开发页面选择的Blink版本,请和Pom依赖Blink版本保持一致。
- Blink相关依赖,scope请使用provided,即
<scope>provided</scope>
- 其他第三方依赖请采用Shade方式打包
UDX分类
实时计算Flink版支持以下3类自定义函数。
UDX分类 | 描述 |
---|---|
UDF(User Defined Scalar Function) | 用户自定义标量值函数,其输入与输出是一对一的关系,即读入一行数据,写出一条输出值。 |
UDAF(User Defined Aggregation Function) | 自定义聚合函数,其输入与输出是多对一的关系,即将多条输入记录聚合成一条输出值。可以与SQL中的GROUP BY语句一起使用。 |
UDTF(User Defined Table-valued Function) | 自定义表值函数,调用一次函数输出多行或多列数据。 |
注册使用
-
在资源引用中新建开发完成的jar包;
-
在作业的编辑窗口的顶部,输入自定义函数声明,示例如下。
CREATE FUNCTION stringLengthUdf AS 'com.hjc.test.blink.sql.udx.StringLengthUdf';
参数与返回值类型
实时计算Flink版数据类型 | Java类型 |
---|---|
TINYINT | java.lang.Byte |
SMALLINT | java.lang.Short |
INT | java.lang.Integer |
BIGINT | java.lang.Long |
FLOAT | java.lang.Float |
DOUBLE | java.lang.Double |
DECIMAL | java.math.BigDecimal |
BOOLEAN | java.lang.Boolean |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
CHAR | java.lang.Character |
STRING | java.lang.String |
VARBINARY | java.lang.byte[] |
ARRAY | 暂不支持 |
MAP | 暂不支持 |
获取自定义函数参数
自定义函数中提供了可选的open(FunctionContext context)
方法,FunctionContext
具备参数传递功能,自定义配置项可以通过此对象来传递。
假设,您需要在作业中添加如下两个参数。
testKey1=lincoln
test.key2=todd
以UDTF为例,在Open方法中通过context.getJobParameter
即可获取,示例如下。
public void open(FunctionContext context) throws Exception {
String key1 = context.getJobParameter("testKey1", "empty");
String key2 = context.getJobParameter("test.key2", "empty");
System.err.println(String.format("end open: key1:%s, key2:%s", key1, key2));
}
自定义标量函数(UDF)
定义
自定义标量函数(UDF)将0个、1个或多个标量值映射到一个新的标量值。
业务代码
UDF需要在ScalarFunction类中实现eval
方法。open
方法和close
方法可选。
注意 UDF默认对于相同的输入会有相同的输出。如果UDF不能保证相同的输出,例如,在UDF中调用外部服务,相同的输入值可能返回不同的结果,建议您使用
override isDeterministic()
方法,返回False
。否则在某些条件下,输出结果不符合预期。例如,UDF算子前移。
示例代码如下。
package com.hjc.test.blink.sql.udx;
import org.apache.flink.table.functions.FunctionContext;
import org.apache.flink.table.functions.ScalarFunction;
public class StringLengthUdf extends ScalarFunction {
// 可选,open方法可以不写。
// 如果编写open方法需要声明'import org.apache.flink.table.functions.FunctionContext;'。
@Override
public void open(FunctionContext context) {
}
public long eval(String a) {
return a == null ? 0 : a.length();
}
public long eval(String b, String c) {
return eval(b) + eval(c);
}
//可选,close方法可以不写。
@Override
public void close() {
}
}
编写SQL语句
在指定的Class中编写SQL语句,自定义函数中SQL语句示例如下。
-- udf str.length()
CREATE FUNCTION stringLengthUdf AS 'com.hjc.test.blink.sql.udx.StringLengthUdf';
create table sls_stream