【Flink系列】开启jdbc批量写入

背景

开发Flink应用要求计算结果实时写入数据库的,一般业务写入TPS在600-800,如果生产同时跑十几个任务,数据库写入TPS接近一万,对数据库造成了较大压力,使用窗口的优化方向不可行:

1. 计算任务的key值较为分散(如用户,商户维度),小窗口(1分钟、5分钟)计算无法减少写入次数,大窗口(10分钟、1小时)实时性太差;

2. 无法保证上游流水100%有序准时到达,使用窗口计算容易漏算流水;


优化思路

使用Flink应用对流水进行计算和统计,结果一般字段较少,每条计算结果的数据量不大,如果开启批量写入,可以降低和数据库之间的网络交换次数,也可提升数据库的数据写入效率;


数据库连接配置

  • rewriteBatchedStatements        

配置此参数为true以后,jdbc驱动会在executeBatch时将SQL改写,将多条Insert语句合并为一条,效果如下:

改写前:

INSERT INTO `t` (`a`) VALUES(10);
INSERT INTO `t` (`a`) VALUES(11);
INSERT INTO `t` (`a`) VALUES(12);

改写后:

INSERT INTO `t` (`a`) VALUES(10),(11),(12);
  • useServerPrepStmts

这个参数是用来节省数据库SQL解析和执行计划消耗的,开启useServerPrepStmts以后,服务器可以将已经解析的SQL反复使用,只在每次客户端提交新的写入请求时填入'?'占位符的参数;

值得注意的是,useServerPrepStmts开启后,客户端不再对SQL预编译,也

### 使用 Flink JDBC Connector 进行批量插入 为了实现批处理模式下的数据插入操作,可以配置 `JdbcExecutionOptions` 来设置批量大小以及并发度等参数[^1]。 下面是一个完整的 Scala 代码示例来展示如何利用 Apache FlinkJDBC Connector 执行批量插入: ```scala import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment import org.apache.flink.connector.jdbc.{JdbcConnectionOptions, JdbcExecutionOptions, JdbcSink} import org.apache.flink.types.Row val env = StreamExecutionEnvironment.getExecutionEnvironment // 定义要写入的数据源 val dataStream = env.fromElements( Row.of(1.asInstanceOf[Integer], "Alice"), Row.of(2.asInstanceOf[Integer], "Bob")) dataStream.addSink(JdbcSink.sink( "INSERT INTO users (id, name) VALUES (?, ?)", // SQL 插入语句模板 new JdbcStatementBuilder { override def accept(ps: PreparedStatement, row: Row): Unit = { ps.setInt(1, row.getField(0).asInstanceOf[Int]) ps.setString(2, row.getField(1).toString) } }, JdbcExecutionOptions.builder() .withBatchSize(5) // 设置每批次提交记录数 .withBatchIntervalMs(200L) // 设置最大等待时间(ms),超过此时间未满也强制提交 .build(), new JdbcConnectionOptions.JdbcConnectionOptionsBuilder() .withUrl("jdbc:mysql://localhost:3306/testdb") // 数据库连接字符串 .withDriverName("com.mysql.cj.jdbc.Driver") // 驱动名称 .withUsername("root") // 用户名 .withPassword("password") // 密码 .build())) env.execute("Flink Batch Insert Example") ``` 上述程序创建了一个简单的流环境,并定义了一组测试数据作为输入。接着构建了针对 MySQL 表名为 `users` 的 Sink 函数实例,在其中指定了具体的字段映射逻辑和数据库访问细节。最后启动执行流程完成整个过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值