【Flink】FlinkSQL-动态表和持续查询概念

FlinkSQL-动态表和持续查询

详细说明下Flink流中表的概念,这里与关系型数据库的表进行对比。

关系型数据库表 Flink流处理表
处理的数据对象 字段元组的有界集合 字段元组的无限序列
查询Query对数据的访问 可以访问到完整的输入 无法访问到所有数据,必须持续等待流式输入
查询终止条件 生成固定大小的结果集后终止 永不停止,根据持续收到的数据不断更新结果集

从概念来说,关系型数据库表针对批数据进行处理,流处理表针对流式数据进行处理。

动态表

Dynamic Tables,先说说动态表的概念,动态表是Flink Table/SQL的概念,在数据流中,数据记录是源源不断的,通过流创建的数据表在不断发生动态变化,这就是动态表。

持续查询

Continuous Query,对动态表可进行查询,由于数据是不断变化的,因此对动态表的查询也是不断变化的,一致随着新数据的到来而继续执行,这样的查询被称为持续查询。持续查询的结果也是一个动态表。

持续查询的步骤:

1)流被转换为动态表

2)对动态表进行持续查询,生成新的动态表

3)生成的动态表被转换成流

持续查询结果转换成流(Stream)

  1. 对于简单的持续查询,例如select user,age from user_info,持续查询的结果是不会对原始数据发生变化的,这种属于追加查询,直接调用toDataStream方法将动态表转换成流
java 复制代码
//查询mysql数据库test下tb1表
Table table = tabEnv.sqlQuery("select * from tb1");
//将table转换成DataStream并控制台输出
tabEnv.toDataStream(table).print()
  1. 对于聚合操作的持续查询,例如select user_id,count(1) from user_info,持续查询的结果会随着数据流的到来发生更新,这种属于更新查询,调用toChangelogStream方法将动态表转换成流
java 复制代码
Table table = tabEnv.sqlQuery("select user_id,count(1) from test_topic group by user_id");
//table对象转换成toChangelogStream 因为涉及到更新
DataStream<Row> rowDataStream = tabEnv.toChangelogStream(table);

不同持续查询下的编码方式

动态表也可以实现INSERT、UPDATE、DELETE进行持续的操作,将动态表转换成流或者写入外部系统需要对这些编码进行处理。通过发送的编码的方式告诉外部系统要执行的操作。

  • 仅追加流Apend

+I代表插入

  • 撤回流Retract 包含了add消息和撤回消息

+U代表新增 -U代表删除

shell 复制代码
+I[123, 1]  第一次插入 +I
-U[123, 1]  修改操作 先标识删除
+U[123, 2] 修改操作 后标识插入
-U[123, 2] .....
+U[123, 3]
-U[123, 3]
+U[123, 4]
  • 更新插入流(Upsert)

时间属性

DataStreamApI时间语义上有事件时间以及处理时间,当然TableAPI也有这两个时间语义。

事件时间事项可以在DDL创建表时指定,通过增加一个字段,用Watermark语句来定义。、

sql 复制代码
CREATE TABLE test_topic (
  user_id BIGINT,
  item_id BIGINT,
  ts BIGINT,      
  event_time AS TO_TIMESTAMP_LTZ(ts, 3),  
  WATERMARK FOR event_time AS event_time - INTERVAL '60' SECOND   --定义事件时间
) WITH (
  'connector' = 'kafka',
  'topic' = 'Test-Topic',  
  'properties.bootstrap.servers' = 'hb1:9092,hb2:9092,hb3:9092', 
  'properties.group.id' = 'flink_sql_group',  
  'scan.startup.mode' = 'earliest-offset',  
  'format' = 'json',  
  'json.fail-on-missing-field' = 'false',
  'json.ignore-parse-errors' = 'true'  
);

ts字段表示事件时间,设置水位线将延迟水位设置60s

处理时间语义呢,在DDL时通过额外声明一个字段,来保存处理时间。

sql 复制代码
CREATE TABLE test_topic (
  user_id BIGINT,
  item_id BIGINT,
 ts AS PROCTIME()  --处理时间
) WITH (
  'connector' = 'kafka',
  'topic' = 'Test-Topic',  
  'properties.bootstrap.servers' = 'hb1:9092,hb2:9092,hb3:9092', 
  'properties.group.id' = 'flink_sql_group',  
  'scan.startup.mode' = 'earliest-offset',  
  'format' = 'json',  
  'json.fail-on-missing-field' = 'false',
  'json.ignore-parse-errors' = 'true'  
);

数据输入:{"user_id":124,"item_id":123} ...

数据输出:

相关推荐
矶鹬笛手12 小时前
(2.2) 新一代信息技术及应用
大数据·云计算·区块链·时序数据库
Y***K43413 小时前
MySQL网站
数据库·mysql
q***448113 小时前
postgresql链接详解
数据库·postgresql
菜鸟‍13 小时前
【后端学习】MySQL数据库
数据库·后端·学习·mysql
污斑兔13 小时前
腾讯云 CloudBase 数据库 CRUD 完整指南
数据库·云计算·腾讯云
tuokuac14 小时前
批量新增操作为什么要加@Transactional注解
数据库
汤姆yu14 小时前
基于python大数据的小说数据可视化及预测系统
大数据·python·信息可视化
立控信息LKONE14 小时前
库室采购安全设施设备——自主研发、国产化监管一体机
大数据·安全
q***99416 小时前
Redis的Spring配置
数据库·redis·spring
S***y39616 小时前
MySQL视频
数据库·mysql