flink使用StatementSet降低资源浪费

背景

项目中有很多ods层(mysql 通过cannal)kafka,需要对这些ods kakfa做一些etl操作后写入下一层的kafka(dwd层)。

一开始采用的是executeSql方式来执行每个ods→dwd层操作,即类似:

复制代码
 def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)
    val configuration: Configuration = tableEnv.getConfig.getConfiguration
 
    tableEnv.createTemporarySystemFunction("etl_handle", classOf[ETLFunction])
 
    // source/sink ddl
    tableEnv.executeSql(CREATE_DB_DDL)
    tableEnv.executeSql(SOURCE_KAFKA_ODS_TABLE1)
    tableEnv.executeSql(SINK_KAFKA_DWD_TABLE1)
    tableEnv.executeSql(SOURCE_KAFKA_ODS_TABLE2)
    tableEnv.executeSql(SINK_KAFKA_DWD_TABLE2)
    ....
 
    // insert dml,在insert语句中调用etl_handle进行预处理和写入
    tableEnv.executeSql(INSERT_DWD_TABLE1)
    tableEnv.executeSql(INSERT_DWD_TABLE2)
    ... 
}

当有多个ods->dwd操作放在同一个flink作业中时,发现这种方式会导致每次insert操作都是单独的DAG,非常消耗资源,特别是这些处理都是比较轻量级的,最好是能融合在同一个DAG中共享资源。

解决方案

查看flink文档:INSERT 语句 | Apache Flink

因此,可以采用statementset的方式,将不同insert sql进行分组执行,每组的insert sql会先被缓存到 StatementSet 中,并在StatementSet.execute() 方法被调用时,同一组的 insert sql(sink) 会被优化成一张DAG共用taskmanager,减少资源浪费,即类似:

复制代码
def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)
    val configuration: Configuration = tableEnv.getConfig.getConfiguration
 
    tableEnv.createTemporarySystemFunction("etl_handle", classOf[ETLFunction])
 
    // source/sink ddl
    tableEnv.executeSql(CREATE_DB_DDL)
    tableEnv.executeSql(SOURCE_KAFKA_ODS_TABLE1)
    tableEnv.executeSql(SINK_KAFKA_DWD_TABLE1)
    tableEnv.executeSql(SOURCE_KAFKA_ODS_TABLE2)
    tableEnv.executeSql(SINK_KAFKA_DWD_TABLE2)
    ....
 

     // insert dml
    tableEnv.createStatementSet()
      .addInsertSql(INSERT_DWD_TABLE1)
      .addInsertSql(INSERT_DWD_TABLE2)
      .addInsertSql(INSERT_DWD_TABLE3)
      .execute()
 
 
    tableEnv.createStatementSet()
      .addInsertSql(INSERT_DWD_TABLE4)
      .addInsertSql(INSERT_DWD_TABLE5)
      .addInsertSql(INSERT_DWD_TABLE6)
      .execute()
}

其他

如果是纯flink sql而不用data stream api,也是可以达到同样的效果的。

相关推荐
武子康1 小时前
大数据-253 离线数仓 - Airflow 入门与任务调度实战:DAG、Operator、Executor 部署排错指南
大数据·后端·apache hive
guoji77882 小时前
2026年Gemini 3 Pro vs 豆包2.0深度评测:海外顶流与国产黑马谁更强?
大数据·人工智能·架构
TDengine (老段)2 小时前
TDengine IDMP 组态面板 —— 工具箱
大数据·数据库·时序数据库·tdengine·涛思数据
网络工程小王3 小时前
【大数据技术详解】——Kibana(学习笔记)
大数据·笔记·学习
zxsz_com_cn5 小时前
设备预测性维护方案设计的关键要素
大数据·人工智能
唐天下闻化5 小时前
连锁数字化改造8成翻车?三维避坑实录
大数据
坚持学习前端日记7 小时前
从零开始构建小说推荐智能体 - Coze 本地部署完整教程
大数据·人工智能·数据挖掘
IDIOT___IDIOT7 小时前
关于 git 进行版本管理的时候 gitignore 写入忽略规则而不生效的问题
大数据·git·elasticsearch
不想看见4047 小时前
Git 误删急救手册
大数据·git·elasticsearch