Flink流式处理框架中的Table API和Flink SQL

一、Table  API和Flink  SQL是什么?

1)Flink对批处理和流处理,提供了统一的上层API;

2)Table  API是一套内嵌在Java和Scala语言中的查询API,它允许以非常直观的方式组合来自一些关系运算符的查询;

3)Flink的SQL支持基于实现了SQL标准的Apache  Calcite;

Flink流式处理框架中的Table API和Flink SQL_第1张图片

 

1、基本程序结构

1)Table  API和SQL的程序结构,与流式处理的程序结构十分类似

Flink流式处理框架中的Table API和Flink SQL_第2张图片

2、创建TableEnvironment

1)创建表的执行环境,需要将flink流处理的执行环境传入;

2)TableEnvironment是flink中集成Table API和SQL的核心概念,所有对表的操作都基于TableEnvironment

      —— 注册Catalog

      —— 在Catalog中注册表

      —— 执行SQL查询

      —— 注册用户自定义函数(UDF)

 

3、配置TableEnvironment

1)配置老版本planner的流式查询

Flink流式处理框架中的Table API和Flink SQL_第3张图片

2)配置老版本planner的批式查询

3)配置blink  planner的流式查询

Flink流式处理框架中的Table API和Flink SQL_第4张图片

 4)配置blink  planner的批式查询

Flink流式处理框架中的Table API和Flink SQL_第5张图片

 

二、表(Table)

1)TableEnvironment可以注册目录Catalog,并可以基于Catalog注册表;

2)表(Table)是由一个“标识符”(identifier)来指定的,由3部分组成:Catalog名、数据库(database)名和对象名;

3)表可以是常规的,也可以是虚拟的(视图,View);

4)常规表(Table)一般可以用来描述外部数据,比如文件、数据库表或消息队列的数据,也可以直接从DataStream转换而来;

5)视图(View)可以从现有的表中创建,通常是Table  API或者SQL查询的一个结果表;

 

1、创建表

1)TableEnvironment可以调用.connect()方法,连接外部系统,并调用.createTemporaryTable()方法,在Catalog中注册表;

Flink流式处理框架中的Table API和Flink SQL_第6张图片

2)可以创建Table来描述文件数据,它可以从文件中读取,或者将数据写入文件

Flink流式处理框架中的Table API和Flink SQL_第7张图片

 

2、表的查询——Table  API

1)Table  API是集成在Scala和Java语言内的查询API;

2)Table API基于代表“表”的Table类,并提供一整套操作处理的方法API;这些方法会返回一个新的Table对象,表示对输入表应用转换操作的结果;

3)有些关系型转换操作,可以由多个方法调用组成,构成链式调用结构;

Flink流式处理框架中的Table API和Flink SQL_第8张图片

4)Flink的SQL集成,基于实现了SQL标准的Apache Calcite;

5)在Flink中,用常规字符串来定义SQL查询语句;

6)SQL查询的结果,也是一个新的Table;

 

3、将DataStream转换成表

1)对于一个DataStream,可以直接转换成Table,进而方便地调用Table API做转换操作;

2)默认转换后的Table schema和DataStream中的字段定义一一对应,也可以单独指定出来;

Flink流式处理框架中的Table API和Flink SQL_第9张图片

 

4、数据类型与Schema的对应

1)DataStream中的数据类型,与表的Schema之间的对应关系,可以有两种:基于字段名称,或者基于字段位置;

2)基于名称(name-based)

3)基于位置(position-based)

 

5、创建临时视图(Temporary  View)

1)基于DataStream创建临时视图

Flink流式处理框架中的Table API和Flink SQL_第10张图片

2)基于Table创建临时视图

6、输出表

1)表的输出,是通过将数据写入TableSink来实现的;

2)TableSink是一个通用接口,可以支持不同的文件格式、存储数据库和消息队列;

3)输出表最直接的方法,就是通过Table.insertInto()方法将一个Table写入注册过的TableSink中

Flink流式处理框架中的Table API和Flink SQL_第11张图片

 

7、输出到文件

Flink流式处理框架中的Table API和Flink SQL_第12张图片

 

8、更新模式

1)对于流式查询,需要声明如何在表和外部连接器之间执行转换;

2)与外部系统交换的消息类型,由更新模式(Update Mode)指定

》》追加(Append)模式

     —— 表只做插入操作,和外部连接器只交换插入(Insert)消息;

》》撤回(Retract)模式

      —— 表和外部连接器交换添加(Add)和撤回(Retract)消息;

      —— 插入操作(Insert)编码为Add消息;删除(Delete)编码为Retract消息;更新(Update)编码为上一条的Retract和下一条的Add消息;

》》更新插入(Upsert)模式

      —— 更新和插入都被编码为Upsert消息;删除编码为Delete消息;

 

9、输出到Kafka

1)可以创建Table来描述kafka中的数据,作为输入或输出的TableSink

Flink流式处理框架中的Table API和Flink SQL_第13张图片

 

10、输出到ES

1)可以创建Table来描述ES中的数据,作为输出的TableSink

Flink流式处理框架中的Table API和Flink SQL_第14张图片

 

11、输出到MySQL

1)可以创建Table来描述MySQL中的数据,作为输入和输出

Flink流式处理框架中的Table API和Flink SQL_第15张图片

 

12、将Table转换成DataStream

1)表可以转换为DataStream或DataSet,这样自定义流处理或批处理程序就可以继续在Table API或SQL查询的结果上运行了;

2)将表转换为DataStream或DataSet时,需要指定生成的数据类型,即要将表的每一行转换成的数据类型;

3)表作为流式查询的结果,是动态更新的;

4)转换有两种转换模式:追加(Append)模式和撤回(Retract)模式;

》》追加模式(Append  Mode)

      ——  用于表只会被插入(Insert)操作更改的场景

》》撤回模式(Retract  Mode)

      ——  用于任何场景,有些类似于更新模式中Retract模式,它只有Insert和Delete两类操作;

      ——  得到的数据会增加一个Boolean类型的标识位(返回的第一个字段,用它来标识到底是新增的数据(Insert)),还是被删除的数据(Delete)。

13、查看执行计划

1)Table API提供了一种机制来解释计算表的逻辑和优化查询计划;

2)查看执行计划,可以通过TableEnvironment.explain(table)方法或TableEnvironment.explain()方法完成,返回一个字符串,描述三个计划:

》》优化的逻辑查询计划;

》》优化后的逻辑查询计划;

》》实际执行计划;

Flink流式处理框架中的Table API和Flink SQL_第16张图片

14、流处理和关系代数的区别

 

关系代数(表)/SQL

流处理

处理的数据对象

字段元组的有界集合

字段元组的无限序列

查询(Query

对数据的访问

可以访问到完整的数据输入

无法访问所有数据,

必须持续“等待”流式输入

查询终止条件

生成固定大小的结果集后终止

永不停止,根据持续收到的数据不断更新查询结果

 

15、动态表(Dynamic  Tables)

1)动态表是Flink对流数据的Table API和SQL支持的核心概念;

2)与表示批处理数据的静态表不同,动态表是随时间变化的;

》》持续查询(Continuous  Query)

(1)动态表可以像静态的批处理表一样进行查询,查询一个动态表会产生持续查询(Continuous  Query);

(2)连续查询永远不会终止,并会生成另一个动态表;

(3)查询会不断更新其动态结果表,以反映其动态输入表上的更改;

 

16、动态表和持续查询

Flink流式处理框架中的Table API和Flink SQL_第17张图片

》》流式表查询的处理过程:

(1)流被转换为动态表;

(2)对动态表计算连续查询,生成新的动态表;

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

 

17、将流转换成动态表

1)为了处理带有关系查询的流,必须先将其转换为表;

2)从概念上将,流的每个数据记录,都被解释为结果表的插入(Insert)修改操作;

Flink流式处理框架中的Table API和Flink SQL_第18张图片

 

18、持续查询

1)持续查询会在动态表上做计算处理,并作为结果生成新的动态表;

Flink流式处理框架中的Table API和Flink SQL_第19张图片

 

19、将动态表转换成DataStream

1)与常规的数据库表一样,动态表可以通过插入(Insert)、更新(Update)和删除(Delete)更改,进行持续的修改;

2)将动态表转换为流或将其写入外部系统时,需要对这些更改进行编码;

》》仅追加(Append-only)流

       ——  仅通过插入(Insert)更改来修改的动态表,可以直接转换为仅追加流;

》》撤回(Retract)流

       ——  撤回流流是包含两类消息的流:添加(Add)消息和撤回(Retract)消息;

》》Upsert(更新插入)流

        ——  Upsert流也包含两种类型的消息:Upsert消息和删除(Delete)消息;

Flink流式处理框架中的Table API和Flink SQL_第20张图片

 

20、时间特性(Time  Attributes)

1)基于时间的操作(比如Table  API和SQL中窗口操作),需要定义相关的时间语义和时间数据来源的信息;

2)Table可以提供一个逻辑上的时间字段,用于在表处理程序中,指示时间和访问相应的时间戳;

3)时间属性,可以是每个表schema的一部分。一旦定义了时间属性,它就可以作为一个字段引用,并且可以在基于时间的操作中使用;

4)时间属性的行为类似于常规时间戳,可以访问,并且进行计算;

 

21、定义处理时间(Processing  Time)

1)处理时间语义下,允许表处理程序根据机器的本地时间生成结果。它是时间的最简单概念,它既不需要提取时间戳,也不需要生成Watermark;

》》由DataStream转换成表时指定

(1)在定义Schema期间,可以使用.proctime,指定字段名定义处理时间字段;

(2)这个proctime属性只能通过附加逻辑字段,来扩展物理schema。因此,只能在schema定义的末尾定义它

》》定义Table  Schema时指定

Flink流式处理框架中的Table API和Flink SQL_第21张图片

》》在创建表的DDL中定义

Flink流式处理框架中的Table API和Flink SQL_第22张图片

2)事件时间语义,允许表处理程序根据每个记录中包含的时间生成结果。这样即使在有乱序事件或者延迟事件时,也可以获得正确的结果。

3)为了处理无序事件,并区分流中的准时和迟到事件;Flink需要从事件数据中,提取时间戳,并用来推进事件时间的进展;

4)定义事件时间,同样有三种方法:

       》由DataStream转换成表时指定

       》定义Table  Schema时指定

       》在创建表的DDL中定义

》》由DataStream转换成表时指定

(1)在DataStream转换成Table,使用.rowtime可以定义事件时间属性

Flink流式处理框架中的Table API和Flink SQL_第23张图片

(2)定义Table  Schema时指定

Flink流式处理框架中的Table API和Flink SQL_第24张图片

(3)在创建表的DDL中定义

Flink流式处理框架中的Table API和Flink SQL_第25张图片

 

22、窗口

1)时间定义,要配合窗口操作才能发挥作用;

2)在Table  API和SQL中,主要有两种窗口

》》Group  Windows(分组窗口)

       ——  根据时间或行计数间隔,将行聚合到有限的组(Group)中,并对每个组的数据执行一次聚合函数;

》》Over Windows

       ——  针对每个输入行,计算相邻行范围内的聚合;

 

22.1 Group  Windows

(1)Group  WIndows是使用window(w:GroupWindow)子句定义的,并且必须由as子句指定一个别名。

(2)为了按窗口对表进行分组,窗口的别名必须在group by子句中,像常规的分组字段一样引用

Flink流式处理框架中的Table API和Flink SQL_第26张图片

(3)Table  API提供了一组具有特定语义的预定义Window类,这些类会被转换为底层DataStream或DataSet的窗口操作;

 

22.2 滚动窗口(Tumbling  windows)

(1)滚动窗口要用Tumble类来定义

Flink流式处理框架中的Table API和Flink SQL_第27张图片

 

22.3 滑动窗口(Sliding  windows)

(1)滑动窗口要用slide类来定义

Flink流式处理框架中的Table API和Flink SQL_第28张图片

 

22.4  会话窗口(Session  windows)

(1)会话窗口要用Session类来定义

Flink流式处理框架中的Table API和Flink SQL_第29张图片

22.5 Over  Windows

(1)Over  window聚合是标准SQL中已有的(over子句),可以在查询的SELECT子句中定义;

(2)Over window聚合,会针对每个输入行,计算相邻行范围内的聚合;

(3)Over windows使用window(w:overwindows*)子句定义,并在select()方法中通过别名来引用

Flink流式处理框架中的Table API和Flink SQL_第30张图片

4)Table  API提供了Over类,来配置Over窗口的属性;

 

22.6  无界Over  Windows

1)可以在事件时间或处理时间,以及指定为时间间隔,或行计数的范围内,定义Over windows

2)无界的over  window是使用常量指定的

Flink流式处理框架中的Table API和Flink SQL_第31张图片

 

22.7  有界Over Windows

1)有界的over  window是用间隔的大小指定的

Flink流式处理框架中的Table API和Flink SQL_第32张图片

 

23、SQL中的Group Windows

1)Group Windows定义在SQL查询的Group By子句中

》》TUMBLE(time_attr,interval)

(1)定义一个滚动窗口,第一个参数是时间字段,第二个参数是窗口长度;

》》HOP(time_attr,interval)

(1)定义一个滑动窗口,第一个参数是时间字段,第二个参数是窗口滑动步长,第三个是窗口长度;

》》SESSION(time_attr,interval)

(1)定义一个会话窗口,第一个参数是时间字段,第二个参数是窗口间隔;

 

24、SQL中的Over  Windows

1)用Over做窗口聚合时,所有聚合必须在同一窗口上定义,也就是说必须是相同的分区、排序和范围;

2)目前仅支持在当前行范围之前的窗口;

3)ORDER  BY必须在单一的时间属性上指定

Flink流式处理框架中的Table API和Flink SQL_第33张图片

 

25、函数(Functions)

1)Flink  Table  API 和SQL为用户提供了一组用于数据转换的内置函数;

2)SQL中支持的很多函数,Table  API和SQL都已经做了实现;

Flink流式处理框架中的Table API和Flink SQL_第34张图片

Flink流式处理框架中的Table API和Flink SQL_第35张图片

 

26、用户自定义函数(UDF)

1)用户定义函数(User-defined  Functions,UDF)是一个重要的特性,它们显著地扩展了查询的表达能力;

2)在大多数情况下,用户定义的函数必须先注册,然后才能在查询中使用;

3)函数通过调用registerFunction()方法在TableEnvironment中注册。当用户定义的函数被注册时,它被插入到TableEnvironment的函数目录中,这样Table  API或SQL解析器就可以识别并正确地解释它;

 

27、标量函数(Scalar  Functions)

1)用户定义的标量函数,可以将0、1或多个标量值,映射到新的标量值;

2)为了定义标量函数,必须在org.apache.flink.table.functions中扩展基类Scalar  Function,并实现(一个或多个)求值(eval)方法;

3)标量函数的行为由求值方法决定,求值方法必须公开声明并命名为eval

Flink流式处理框架中的Table API和Flink SQL_第36张图片

 

28、表函数(Table  Functions)

1)用户定义的表函数,也可以将0、1或多个标量值作为输入参数;与标量函数不同的是,它可以返回任意数量的行行为输出,而不是单个值;

2)为了定义一个表函数,必须扩展org.apache.flink.table.functions中的基类TableFunction并实现(一个或多个)求值方法;

3)表函数的行为由其求值方法决定,求值方法必须是public的,并命名为eval:

Flink流式处理框架中的Table API和Flink SQL_第37张图片

 

29、聚合函数(Aggregate  Functions)

1)用户自定义聚合函数(User-Defined  Aggregate  Functions,UDAGGs)可以把一个表中的数据,聚合成一个标量值;

2)用户定义的聚合函数,是通过继承AggregateFunction抽象类实现的

Flink流式处理框架中的Table API和Flink SQL_第38张图片

3)AggregationFunction要求必须实现的方法:

      ——  createAccumulator()

      ——   accumulate()

      ——   getValue()

4)AggregateFunction的工作原理如下:

       ——  首先,它需要一个累加器(Accumulator),用来保存聚合中间结果的数据结构;可以通过调用createAccumulator()方法创建空累加器;

       ——   随后,对每个输入行调用函数的accumulate()方法来更新累加器;

       ——    处理完所有行后,将调用函数的getValue()方法来计算并返回最终结果;

 

30、表聚合函数(Table  Aggregate  Functions)

1)用户定义的表聚合函数(User-defined  Table  Aggregate  Functions,UDTAGGs),可以把一个表中数据,聚合为具有多行和多列的结果表;

2)用户定义表聚合函数,是通过集成TableAggregateFunction抽象类来实现的;

Flink流式处理框架中的Table API和Flink SQL_第39张图片

3)AggregationFunction要求必须实现的方法:

      ——  createAccumulator()

      ——  accumulate()

      ——  emitValue()

4)TableAggregateFunction的工作原理如下:

      —— 首先,它同样需要一个累加器(Accumulator),它是保存聚合中间结果的数据结构。通过调用createAccumulator()方法可以创建空累加器;

      ——  随后,对每个输入行调用函数的accumulate()方法来更新累加器;

      ——   处理完所有行后,将调用函数的emitValue()方法来计算并返回最终结果;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Flink学习)