- 进入sql客户端
- 查看有哪些设置
- set;
- set;显示的设置不全
- 几种常见的设置
- 启动sql客户端的时候使用初始化脚本
vi ../conf/sql-client-init.sql
写入初始化脚本
使用初始化脚本启动
embedded:内嵌模式
-s yarn-session:指定运行模式
-i ../conf/sql-client-init.sql:指定初始化配置文件
- flink 是一个分布式计算引擎,flink sql只是映射 sql 为分布式计算任务的工具
flink sql 不保存数据,数据需要通过连接器器去外部读取
保存映射关系需要有地方保存映射关系的元元数据,flink 没有类似hive metastore的东西,所以flink 不会保存创建的表结构,如果要保持包结构,可以把创建表的sql 写到 初始化脚本里面,以此到达类似元数据持久化的效果。 - flink sql 支持的类型
默认支持的数据类型
Data Type | Remarks for Data Type |
| |
| |
| |
| |
| |
| |
| |
| Supports fixed precision and scale. |
| |
| |
| |
| |
| |
| |
| |
| Supports only a precision of |
| |
| |
| Supports only interval of |
| |
| |
| |
| |
| |
Structured types | Only exposed in user-defined functions yet. |
- 创建表
flink的表就是一份数据上的映射,创建表定义的映射关系,查询被翻译成执行的流处理job。
sink表是输出数据的映射,不能查询只能插入数据。
- 每个查询就是一个flink job
查询结果
生成的job
- sink表不能查询,只能插入
查询sink表保存信息
- 从固定数据源查询
- 类型装换
cast(原数据字段 as 目标类型)
- 使用当前时间
current_timestamp
时间格式化
- 时间字段
current_timestamp获取当前时间,current_timestamp类型是timestamp_ltz(3)时间精度是毫秒,是带有本地时区的timestamp(3)
timestamp(3)是精确到毫秒,格式滑以后显示为:2024-03-13 23:47:50.058
timestamp是精确到纳秒,格式化后显示为:2024-03-14 03:47:14.518000
可以使用current_timestamp 作为事件字段默认值 ,时间转化 as cast(current_timestamp as timestamp(3))
- 查询去重
distinct
- group by
flink sql 对group要求严格,除了聚合函数以外,查询字段必须全部出现在group by 后面。
- order by 排序只能使用时间字段开头,并且只能升序排序(流模式的情况下)
- with使用连接器,有哪些属性怎么生成?
具体去官方文旦查看
这里以datagen连接器的官方文档的例子
datagen连接器写法
datagen连接器参数
fields.#.max-past的时间单位默认是毫秒
参数 | 是否必选 | 默认值 | 数据类型 | 描述 |
connector | 必须 | (none) | String | 指定要使用的连接器,这里是 'datagen'。 |
rows-per-second | 可选 | 10000 | Long | 每秒生成的行数,用以控制数据发出速率。 |
fields.#.kind | 可选 | random | String | 指定 '#' 字段的生成器。可以是 'sequence' 或 'random'。 |
fields.#.min | 可选 | (Minimum value of type) | (Type of field) | 随机生成器的最小值,适用于数字类型。 |
fields.#.max | 可选 | (Maximum value of type) | (Type of field) | 随机生成器的最大值,适用于数字类型。 |
fields.#.max-past | 可选 | 0 | Duration | 随机生成器生成相对当前时间向过去偏移的最大值,适用于 timestamp 类型。 |
fields.#.length | 可选 | 100 | Integer | 随机生成器生成字符的长度,适用于 char、varchar、binary、varbinary、string。 |
fields.#.start | 可选 | (none) | (Type of field) | 序列生成器的起始值。 |
fields.#.end | 可选 | (none) | (Type of field) | 序列生成器的结束值。 |
- 使用文件系统连接器
csv文件地址
地址:hdfs://vm200:9000/flink/table/fs-table.csv
- 使用连接器的元属性
元数据字段名 字段类型 metadata
字段名 字段类型 metadata from 元数据字段名
virtual表示只读
- 设置水位线
格式: watermark for 事件时间字段 as 事件时间字段 - interval 'n' second
事件时间类型限制: TIMESTAMP(p) or TIMESTAMP_LTZ(p), the supported precision 'p' is from 0 to 3
- 窗口(1.13前语法)
老的窗口函数式把窗口当做一个特殊字段来用
- 窗口1.13后建议使用TVF(table value function) 表值函数
新的TVF是把窗口当做一个表来用
- 分窗以后,窗口内部求聚合
- group sets,一次得到多种分组维度的统计结果
下面的结果4个分组维度,没来一条就统计一次4个维度的结果。
- 所有一组
- 按照action分组
- 按照user_id分组
- 按照action和user_id分组
- 获取窗口时间
- over
开窗相当于在每行的基础上,计算当前行和前后关联数据的关系
分区不是必须的,排序是必须的
分区内必须排序,排序字段只能是时间字段,并且升序
range是时间窗口,rows是计数窗口
开窗从句格式:range/rows between 间隔 preceding and current row,间隔可以是时间,可以是数字,可以是unbounded
开窗从句的上边界只能是 current row(当前行)
开窗从句默认值:unbounded preceding and current row
- flink over 开窗函数和 TVF 的窗口函数的区别
- 两者本质上都对数据的分区,然后进行区内数据的计算
- over是按照字段分区同一分区的数据是不连续的,TVF的窗口把一段连续的数据数据划为一个区,一定时间内,或者连续多少个。
- 执行模式
一般设置成流模式,如果设置成批模式不能用无界流查询。
当设置成流模式的时候有些有界流处理结果和预期不一样
流模式结果下的开窗结果和批模式的开机结果相比,前面少了几条?
待确认....
批模式结果没用指定了水位线的表
- flinksql 查询记录 op列 +I -U +U -D解释
- +I 是新增的一行记录
- -U 是回撤一条数据
- +U是添加了一条数据(在回撤的基础上新增了一条数据),-U和+U两条 合起来就是一次更新
- -D 是删除了数据
- 使用 row_number() over 实现topN
- top1等于去重
- join
join依赖状态的保存,如果不设置 ttl很可能保存的状态超出内存限制,但是如果设置的ttl太短 会导致结果不精确。
- join
如果设置了不续期的TTL 10秒,那么就相等10秒的滚动窗口join
- 间隔join
- lookup 查询
效果是 通过左表里面右表的主键Id,去查询数据关联
需要右表有主键,并且右表的主键和左表关联。
要求时间字段类型一样
语法 join table for system_time as of 左表时间字段
- hint 可以在本次sql中临时修改连接器属性
sql/*+ OPTIONS('属性key'='属性值') */
- 并集 交集 差集 in 子查询
- flink字符串拼接使用的 ||
- 其他系统函数
具体用法,可以查官方文档
- 使用模块hive
去flink官网下载对应版本的hive连接器jar包(flink-sql-connector-hive-3.1.3_2.12-1.17.2.jar),然后放到flink的lib目录下面
重启flink,然后加载hive
加载hive模块以后就能使用hive的函数了select split('a-b','-'); flink 没有 solit 函数。
有的flink版本需要hadoop-mapreduce-client-core.jar才能加载hive,hadoop-3.3.6/share/hadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar 到flink的lib目录下(添加jar以后需要重启flink)。实测1.17.2没有这个问题。
- 导入hive 连接器jar包以后,文件系统连接器使用异常问题
hive连接器的jar包用的老版本的 planner,老版本的planner位于flink/opt/flink-table-planner_2.12-1.17.2.jar
用flink/opt/flink-table-planner_2.12-1.17.2.jar 替换 flink/lib/flink-table-planner-loader-1.17.2.jar,然后重启flink - 读取kafka数据,和fixed分区器
kafka
- kafka upsert 流, kafka-upsert 才能插入数据
'connector' = 'upsert-kafka', - mysql连接器
需要导入连接器驱动mysql-connector-java.jar和mysql驱动包
如果有主键就会一upset方式自动添加或者修改数据,如果没有主键,就只会添加新数据,所以一般都要有主键
也就是说有主键以后插入一条同id 的数据,效果是更新,没有主键会在flink的 任务里面报错,flink sql 客户端不会报错。
mysql连接器目前是不支持update 操作的,只能查询和插入,通过upset更新。
- 查看fink作业列表
show jobs
- 创建保存点和从保存点恢复
- catalog介绍
catalog是数据库之上的一层是一个目录,目的是打通flink和外部数据的映射,不需要我们一张表一张表的映射,直接就能查询
catalog 目前支持hive和jdbc(mysql和postgresql)
我们可以通过 catalog名字.database名字.table名字,使用别的catalog下面的表,可以查询可以连接。
我们可以在初始化sql中映射catalog,然后就能直接使用外部数据库的表了。
catalog和数据库的操作
- 使用catalog映射 mysql,是只读的,不能建表
- 使用catalog 链接 hive,这是创建表和读取数据的,并且这里创建的表是可以持久化到hive里面,但是catalog不能持久化,需要每次使用初始化脚本创建
甚至可以在 hive 的catalog 里面创建映射到mysql的表,并且它也是可以持久化的。
flink 是连接到 hive 的metastore上读取数据的
- 在Java代码中使用flink sql
依赖
- 自定义函数
标量函数
表函数
聚合函数
表聚合函数