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 小时前
Flink-1.19.0源码详解-番外补充3-StreamGraph图
大数据·flink
资讯分享周1 小时前
Alpha系统联结大数据、GPT两大功能,助力律所管理降本增效
大数据·gpt
G皮T3 小时前
【Elasticsearch】深度分页及其替代方案
大数据·elasticsearch·搜索引擎·scroll·检索·深度分页·search_after
TDengine (老段)3 小时前
TDengine STMT2 API 使用指南
java·大数据·物联网·时序数据库·iot·tdengine·涛思数据
用户Taobaoapi20145 小时前
母婴用品社媒种草效果量化:淘宝详情API+私域转化追踪案例
大数据·数据挖掘·数据分析
G皮T5 小时前
【Elasticsearch】检索排序 & 分页
大数据·elasticsearch·搜索引擎·排序·分页·检索·深度分页
Edingbrugh.南空7 小时前
Flink MySQL CDC 环境配置与验证
mysql·adb·flink
小新学习屋9 小时前
Spark从入门到熟悉(篇三)
大数据·分布式·spark
rui锐rui9 小时前
大数据学习2:HIve
大数据·hive·学习
G皮T9 小时前
【Elasticsearch】检索高亮
大数据·elasticsearch·搜索引擎·全文检索·kibana·检索·高亮