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,也是可以达到同样的效果的。

相关推荐
com_4sapi3 分钟前
2025 权威认证头部矩阵系统全景对比发布 双榜单交叉验证
大数据·c语言·人工智能·算法·矩阵·机器人
鲸能云1 小时前
政策解读 | “十五五”能源规划下储能发展路径与鲸能云数字化解决方案
大数据·能源
五度易链-区域产业数字化管理平台2 小时前
五度易链大数据治理实战:从数据孤岛到智能决策
大数据
激动的小非2 小时前
电商数据分析报告
大数据·人工智能·数据分析
ITVV2 小时前
湖仓一体部署
大数据·数据湖·湖仓一体
2501_933509074 小时前
无锡制造企税惠防错指南:知了问账帮守政策红利线
大数据·人工智能·微信小程序
F36_9_4 小时前
如何在沟通不畅导致误解后进行修复
大数据
青云交4 小时前
Java 大视界 -- 基于 Java 的大数据实时数据处理在工业互联网设备协同制造中的应用与挑战
flink·spark·工业互联网·预测性维护·实时数据处理·java 大数据·设备协同制造
数字化脑洞实验室4 小时前
智能决策系统落地后如何进行数据集成与安全保障?
大数据