mysql 5.7驱动包connector_关于使用flink-jdbc-driver写入mysql时失败(flink1.10.0)

导读:在Flink1.10版本中,在Batch环和使用Blink Planner 创建TableSink出现了Batch环境不支持RetractStreamTableSink 和 UpsertStreamTableSink。下面将详细讨论导致该问题的原因及对应的解决方式。

场景

//创建流运行时环境EnvironmentSettings bbSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build();TableEnvironment bsTableEnv = TableEnvironment.create(bbSettings);/*StreamExecutionEnvironment bsEnv = StreamExecutionEnvironment.getExecutionEnvironment();          EnvironmentSettings bsSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build();          StreamTableEnvironment bsTableEnv = StreamTableEnvironment.create(bsEnv, bsSettings);*///输出目标(MySQL) 此处记得需要引入flink-jdbc 及对应的 数据库驱动包bsTableEnv.sqlUpdate("CREATE TABLE sourceTable (" +                     "USER_NAME VARCHAR," +                     "USER_SEX VARCHAR" +                     ")" +                     "WITH (" +                     "'connector.type' = 'jdbc'," +                     "'connector.url' = '"+JDBC_URL+"'," +                     "'connector.table' = 'flink_test_user'," +                     "'connector.driver' = 'com.mysql.jdbc.Driver'," +                     "'connector.username' = 'root'," +                     "'connector.password' = 'Marry583@&%!'," +                     "'connector.write.flush.max-rows' = '1')");//输出目标(MySQL) 此处记得需要引入flink-jdbc 及对应的 数据库驱动包bsTableEnv.sqlUpdate("CREATE TABLE sinkTable (" +                     "USER_NAME VARCHAR," +                     "USER_SEX VARCHAR" +                     ")" +                     "WITH (" +                     /*"'update-mode' = 'append'," +*/                     "'connector.type' = 'jdbc'," +                     "'connector.url' = '"+JDBC_URL+"'," +                     "'connector.table' = 'flink_test_user2'," +                     "'connector.driver' = 'com.mysql.jdbc.Driver'," +                     "'connector.username' = 'root'," +                     "'connector.password' = 'Marry583@&%!'," +                     "'connector.write.flush.max-rows' = '1')");//编写SQL语句bsTableEnv.sqlUpdate("INSERT INTO sinkTable SELECT USER_NAME,USER_SEX FROM sourceTable");//执行bsTableEnv.execute("MySQLDDLTest");

运行结果如下,Batch环境不支持RetractStreamTableSink 和 UpsertStreamTableSink

7161f4973dda812444d2bd099c675479.png

对于RetractStreamTableSink、UpsertStreamTableSink和AppendStreamTableSink的大概区别如下,这里就不做详细讨论。

25700d5affdfdb24437e76937f31c537.png

分析问题

1、首先,查看源码发现BatchTableSink中并不存在UpsertStreamTableSink或AppendStreamTableSink而只有JDBCAppendTableSink,那么为什么会出现上面的错误?

afbf21247ff67ae3b93dd6ce27bb50d5.png

2、查阅资料时一位朋友提到了一些相关信息,大概了解到了默认选择使用UpsertStreamTableSink。那么Flink代码具体是怎么做的?

31f56d7e72054476c076e1ec4b57da99.png

3、我们来跟踪一下源码

在org.apache.flink.table.client.gateway.local.ExecutionContext 的createTableSink方法进行Sink的创建,在这里注意到这两个判断是StreamPlaner或BatchPlaner。

4552033578104fee572d72551dc61c35.png

通过查看这两个判断发现,如果我们采用Blink Planner的话,那么都认为是StreamPlaner。我们在最先创建环境的时候使用了Blink Planer(相比于Old Planner对SQL有更好的支持)。

EnvironmentSettings bbSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build();

通过查看判断发现,Blink Planner一律都默认为是StreamPlanner。那么导致接下来在创建Sink时使用的是StreamTableSourceFactory。

55d4b541090959f9cc26dee55952bac6.png

从StreamTableSourceFactory追踪到JDBCTableSourceSinkFactory工厂的createStreamTableSink方法。发现在创建Sink时创建的是JDBCUpsertTableSink。而JDBCUpsertTableSink实现了UpsertStreamTableSink。

ebe8856b412be304dd3ea6029f6d7d56.png

通过上面的跟踪我们发现了Blink Planner在创建TableSink时,无论环境是Stream还是Batch创建的都是UpsertStreamTableSink。但是Batch环境下并不支持UpsertStreamTableSink,所以最终导致了上述的异常。

RetractStreamTableSink and UpsertStreamTableSink is not supported in Batch environment

关于解决方案

  • 使用流环境
  • 关注Flink github对应的RP

1、使用流环境

//流环境StreamExecutionEnvironment bsEnv = StreamExecutionEnvironment.getExecutionEnvironment();          EnvironmentSettings bsSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build();          StreamTableEnvironment bsTableEnv = StreamTableEnvironment.create(bsEnv, bsSettings);

通过将环境改为流环境虽然可以正确运行,但是使用流环境及批环境还是存在一定差异的。如:批模式会等所有数据都处理完以后,一次性输出最终结果。流模式会持续不断输出结果,以及更新结果,是一种增量模式。对于相同的数据集以及相同的 query,从最终结果上来说,流与批运行的结果是一致的。但是批模式必然要比流模式性能更优(因为计算量更少),流模式的优势是"提前(实时)看到结果"。

2、RP

目前已有人对此问题进行了处理,感兴趣的朋友可以关注一下,尝试拉取并构建。

https://github.com/apache/flink/pull/11045

最后

感谢您的阅读,如果喜欢本文欢迎关注和转发,本头条号将坚持持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值