大数据(9h)FlinkSQL双流JOIN
创始人
2024-03-07 05:26:22

文章目录

  • 1、环境
  • 2、Temporal Joins
    • 2.1、基于处理时间(重点)
      • 2.1.1、设置状态保留时间
    • 2.2、基于事件时间
  • 3、Lookup Join(重点)
  • 4、Interval Joins(基于间隔JOIN)

重点是Lookup JoinProcessing Time Temporal Join,其它随意

1、环境

WIN10+IDEA2021+JDK1.8+本地MySQL8

881.13.62.122.0.32.17.22.0.191.18.24


org.apache.flinkflink-java${flink.version}org.apache.flinkflink-streaming-java_${scala.binary.version}${flink.version}org.apache.flinkflink-clients_${scala.binary.version}${flink.version}org.apache.flinkflink-runtime-web_${scala.binary.version}${flink.version}org.apache.flinkflink-table-planner-blink_${scala.binary.version}${flink.version}org.apache.flinkflink-streaming-scala_${scala.binary.version}${flink.version}org.apache.flinkflink-csv${flink.version}org.apache.flinkflink-json${flink.version}org.slf4jslf4j-api${slf4j.version}org.slf4jslf4j-log4j12${slf4j.version}org.apache.logging.log4jlog4j-to-slf4j${log4j.version}com.alibabafastjson${fastjson.version}org.projectlomboklombok${lombok.version}

2、Temporal Joins

2.1、基于处理时间(重点)

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;public class Hi {public static void main(String[] args) {//创建流执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);//创建流式表执行环境StreamTableEnvironment tbEnv = StreamTableEnvironment.create(env);//双流DataStreamSource> d1 = env.fromElements(Tuple2.of("a", 2),Tuple2.of("b", 3));DataStreamSource

d2 = env.fromElements(new P("a", 4000L),new P("b", 5000L));//创建临时视图tbEnv.createTemporaryView("v1", d1);tbEnv.createTemporaryView("v2", d2);//双流JOINtbEnv.sqlQuery("SELECT * FROM v1 LEFT JOIN v2 ON v1.f0=v2.pid").execute().print();}@Data@NoArgsConstructor@AllArgsConstructorpublic static class P {private String pid;private Long timestamp;} }

结果

+----+-------+-------+-------------+-------------+
| op |    f0 |    f1 |         pid |   timestamp |
+----+-------+-------+-------------+-------------+
| +I |     a |     2 |      (NULL) |      (NULL) |
| -D |     a |     2 |      (NULL) |      (NULL) |
| +I |     a |     2 |           a |        4000 |
| +I |     b |     3 |      (NULL) |      (NULL) |
| -D |     b |     3 |      (NULL) |      (NULL) |
| +I |     b |     3 |           b |        5000 |
+----+-------+-------+-------------+-------------+

2.1.1、设置状态保留时间

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;import java.time.Duration;
import java.util.Scanner;public class Hi {public static void main(String[] args) {//创建流执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);//创建流式表执行环境StreamTableEnvironment tbEnv = StreamTableEnvironment.create(env);//设置状态保留时间tbEnv.getConfig().setIdleStateRetention(Duration.ofSeconds(5L));//双流DataStreamSource> d1 = env.addSource(new AutomatedSource());DataStreamSource d2 = env.addSource(new ManualSource());//创建临时视图tbEnv.createTemporaryView("v1", d1);tbEnv.createTemporaryView("v2", d2);//双流JOINtbEnv.sqlQuery("SELECT * FROM v1 INNER JOIN v2 ON v1.f0=v2.f0").execute().print();}/** 手动输入的数据源(请输入a或b进行测试) */public static class ManualSource implements SourceFunction {public ManualSource() {}@Overridepublic void run(SourceFunction.SourceContext sc) {Scanner scanner = new Scanner(System.in);while (true) {String str = scanner.nextLine().trim();if (str.equals("STOP")) {break;}if (!str.equals("")) {sc.collect(str);}}scanner.close();}@Overridepublic void cancel() {}}/** 自动输入的数据源 */public static class AutomatedSource implements SourceFunction> {public AutomatedSource() {}@Overridepublic void run(SourceFunction.SourceContext> sc) throws InterruptedException {for (long i = 0L; i < 999L; i++) {Thread.sleep(1000L);sc.collect(Tuple2.of("a", i));sc.collect(Tuple2.of("b", i));}}@Overridepublic void cancel() {}}
}

测试结果

2.2、基于事件时间

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;public class Hello {public static void main(String[] args) {//创建流和表的执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);StreamTableEnvironment tbEnv = StreamTableEnvironment.create(env);//创建数据流,设定水位线tbEnv.executeSql("CREATE TABLE v1 (" +"  x STRING PRIMARY KEY," +"  y BIGINT," +"  ts AS to_timestamp(from_unixtime(y,'yyyy-MM-dd HH:mm:ss'))," +"  watermark FOR ts AS ts - INTERVAL '2' SECOND" +") WITH (" +"  'connector'='filesystem'," +"  'path'='src/main/resources/a.csv'," +"  'format'='csv'" +")");tbEnv.executeSql("CREATE TABLE v2 (" +"  x STRING PRIMARY KEY," +"  y BIGINT," +"  ts AS to_timestamp(from_unixtime(y,'yyyy-MM-dd HH:mm:ss'))," +"  watermark FOR ts AS ts - INTERVAL '2' SECOND" +") WITH (" +"  'connector'='filesystem'," +"  'path'='src/main/resources/b.csv'," +"  'format'='csv'" +")");//执行查询tbEnv.sqlQuery("SELECT * " +"FROM v1 " +"LEFT JOIN v2 FOR SYSTEM_TIME AS OF v1.ts " +"ON v1.x = v2.x").execute().print();}
}

打印结果

+----+---+------------+-------------------------+--------+------------+-------------------------+
| op | x |          y |                      ts |     x0 |         y0 |                     ts0 |
+----+---+------------+-------------------------+--------+------------+-------------------------+
| +I | a | 1666540800 | 2022-10-24 00:00:00.000 | (NULL) |     (NULL) |                  (NULL) |
| +I | b | 1666540803 | 2022-10-24 00:00:03.000 |      b | 1666540802 | 2022-10-24 00:00:02.000 |
| +I | c | 1666540806 | 2022-10-24 00:00:06.000 |      c | 1666540803 | 2022-10-24 00:00:03.000 |
+----+---+------------+-------------------------+--------+------------+-------------------------+

3、Lookup Join(重点)

Lookup Join是基于Processing Time Temporal Join

详细链接:https://yellow520.blog.csdn.net/article/details/128070761

4、Interval Joins(基于间隔JOIN)

SQL

SELECT * FROM v1
LEFT JOIN v2 ON v1.x=v2.x AND
v1.y BETWEEN (v2.y - INTERVAL '2' SECOND) AND (v2.y + INTERVAL '1' SECOND)

Java

import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;import java.util.Scanner;import static org.apache.flink.table.api.Expressions.$;public class Hi {public static void main(String[] args) {//创建流和表的执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);StreamTableEnvironment tbEnv = StreamTableEnvironment.create(env);//创建数据流DataStreamSource d1 = env.addSource(new ManualSource());DataStreamSource d2 = env.addSource(new AutomatedSource());//创建动态表,并声明一个额外的字段来作为处理时间字段Table t1 = tbEnv.fromDataStream(d1, $("x"), $("y").proctime());Table t2 = tbEnv.fromDataStream(d2, $("x"), $("y").proctime());//创建临时视图tbEnv.createTemporaryView("v1", t1);tbEnv.createTemporaryView("v2", t2);//执行查询tbEnv.sqlQuery("SELECT * FROM v1 LEFT JOIN v2 ON v1.x=v2.x AND " +"v1.y BETWEEN (v2.y - INTERVAL '2' SECOND) AND (v2.y + INTERVAL '1' SECOND)").execute().print();}/** 手动输入的数据源 */public static class ManualSource implements SourceFunction {public ManualSource() {}@Overridepublic void run(SourceFunction.SourceContext sc) {Scanner scanner = new Scanner(System.in);while (true) {String str = scanner.nextLine().trim();if (str.equals("STOP")) {break;}if (!str.equals("")) {sc.collect(str);}}scanner.close();}@Overridepublic void cancel() {}}/** 自动输入的数据源 */public static class AutomatedSource implements SourceFunction {public AutomatedSource() {}@Overridepublic void run(SourceFunction.SourceContext sc) throws InterruptedException {for (int i = 0; i < 999; i++) {Thread.sleep(801);sc.collect("a");sc.collect("b");}}@Overridepublic void cancel() {}}
}

测试结果

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...