本次分享是由真实案例场景
插入错误复现
URL地址
jdbc:mysql://0.0.0.0:3306/test?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true
此链接是直接从数据库中获取过来为最终存储结果连接地址
最终在使用Spark的df.write.mode方式存储结果数据时出现连接超时的错误
- 存储命令为
df.write.mode(SaveMode.Overwrite).jdbc(url, "table_name", prop)
- 错误报错展示
以上错误显示为:通信链路故障
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
一开始以为是连接中途中断引起的,故而添加了以下参数
autoReconnect=true
- 参数解释说明:
- 指定如果连接丢失,驱动程序是否应尝试自动重新连接
jdbc:mysql://0.0.0.0:3306/test?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true&autoReconnect=true
添加后执行任务还是同样的报错
查找有些资料说是因为时区的问题、JDBC版本的问题、连接超时的问题,导致通信失败,以下放入博客链接
连接驱动问题: https://www.bigtspace.com/archives/9942.html
时区问题: https://blog.csdn.net/lonzgzhouzhou/article/details/128105146
连接超时问题: https://www.cnblogs.com/ZJOE80/p/9405233.html
按照以上几个步骤测试后均不成功
** 之后思考是否是因为Spark在执行时需要先清空表在一条条执行插入导致网络通信事务较大导致的 **
最终尝试添加以下参数
rewriteBatchedStatements=true
- 参数解释说明:
- 指定驱动程序是否应将批处理语句重写为单个语句。这可以在执行许多类似查询时提高性能
添加后最终连接地址
- 指定驱动程序是否应将批处理语句重写为单个语句。这可以在执行许多类似查询时提高性能
jdbc:mysql://0.0.0.0:3306/test?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true&rewriteBatchedStatements=true
- 测试后成功导入
总结: - MySQL中有一个参数叫做rewriteBatchedStatements,它控制着JDBC驱动程序在执行批量插入时是否将多个SQL语句重写为单个语句。当该参数设置为true时,JDBC驱动程序会将多个INSERT语句组合成一个语句,并将其发送到MySQL服务器一次执行,这可以大大提高插入的效率。
- 在使用df.write.mode(SaveMode.Overwrite).jdbc(url, “table_name”, prop)方法向MySQL数据库写入数据时,如果未添加rewriteBatchedStatements=true配置,可能会导致连接超时问题。这是因为当执行SaveMode.Overwrite时,Spark会先删除目标表的所有记录,然后再将新数据写入该表。这个过程可能会非常慢,特别是在写入大量数据时,因为每条INSERT语句都需要发送到MySQL服务器,而没有启用rewriteBatchedStatements时,每个INSERT语句都会作为一个单独的事务来执行,这样会增加网络通信的负担和事务处理的开销。
- 因此,建议在连接MySQL时添加rewriteBatchedStatements=true配置,以便启用批量插入功能,提高写入性能并减少连接超时问题的出现。
完结撒花~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~