Flink Table API是high level使用方式
UDF全称User Define Function,即用户自定义的函数
自定义标量函数可以把 0 个、 1 个或多个标量值转换成一个标量值,它对应的输入是一
行数据中的字段,输出则是唯一的值。所以从输入和输出表中行数据的对应关系看,标量函数是“一对一”的转换。
在Flink中使用标量函数,实现一个继承ScalarFunction的类就好
在Flink流处理中,我们首先可以定义一个POJO当作流处理的数据基本单元:
public class Event {public String user; // 用户名称public String url; // 用户访问的web urlpublic String timeStamp; // 访问时间public Event() {}public Event(String user, String url, String timeStamp) {this.user = user;this.url = url;this.timeStamp = timeStamp;}public Event(String alice, String url, long l) {this.user= alice;this.url = url;this.timeStamp = String.valueOf(l);}@Overridepublic String toString() {return "Event{" +"user='" + user + '\'' +", url='" + url + '\'' +", timeStamp='" + timeStamp + '\'' +'}';}
}
public class UDFTest {public static void main(String[] args) throws Exception {StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// 要想使用自身的UDF,需要先向flink注册udftableEnv.createTemporarySystemFunction("hash", HashFunction.class);// 定义一个数据流SingleOutputStreamOperator eventStream = env.fromElements(new Event("Alice", "./home", 1000L),new Event("Bob", "./cart", 1000L),new Event("Alice", "./prod?id=1", 5 * 1000L),new Event("Cary", "./home", 60 * 1000L),new Event("Bob", "./prod?id=3", 90 * 1000L),new Event("Alice", "./prod?id=7", 105 * 1000L));// 将数据流转换成表tableEnv.createTemporaryView("EventTable", eventStream, $("user"), $("url"),$("timeStamp").as("ts"));// 在flink sql中使用UDFTable result = tableEnv.sqlQuery("SELECT hash(ts) FROM EventTable");// 打印流处理结果tableEnv.toDataStream(result).print();env.execute();}public static class HashFunction extends ScalarFunction {public String eval(@DataTypeHint(inputGroup = InputGroup.ANY) Object o) {return "print:"+o;}}
}
打印结果
+I[print:1000]
+I[print:1000]
+I[print:5000]
+I[print:60000]
+I[print:90000]
+I[print:105000]
跟标量函数一样,表函数的输入参数也可以是 0 个、1 个或多个标量值;不同的是,它可
以返回任意多行数据。
“多行数据”事实上就构成了一个表,所以“表函数”可以认为就是返回一个表的函数,这是一个“一对多”的转换关系。之前我们介绍过的窗口 TVF,本质上就是表函数。
用户自定义聚合函数(User Defined AGGregate function,UDAGG)会把一行或多行数据(也就是一个表)聚合成一个标量值。
这是一个标准的“多对一”的转换。
聚合函数的概念我们之前已经接触过多次,如 SUM()、MAX()、MIN()、AVG()、COUNT()都是常见的系统内置聚合函数。而如果有些需求无法直接调用系统函数解决,我们就必须自定义聚合函数来实现功能了。