Databricks集群通过Spark JDBC连接MySQL无响应问题求助
问题原因分析与解决方案
核心原因梳理
- JDBC配置错误:Scala侧的JDBC URL未指定数据库名,同时缺失MySQL 8.x驱动必备的时区、SSL、超时参数,会导致驱动握手阶段无限等待,表现为无响应;此外Spark JDBC的
table参数错误填写为数据库名,未指定实际查询的表名,也会引发请求异常。 - 驱动版本不兼容:PyMySQL为纯Python实现的驱动,对MySQL服务端版本兼容性更强,而JDBC驱动要求和服务端大版本严格匹配,版本不匹配时会出现连接挂起问题。
- Spark分布式网络权限差异:PyMySQL代码仅在Databricks集群的Driver节点执行,只要Driver节点网络连通即可正常运行;而Spark JDBC默认会调度Worker节点发起数据库连接,如果Worker节点未开放MySQL 3306端口的出口访问权限,就会出现连接超时无响应。
- Scala代码入口逻辑错误:示例代码中对象同时继承
App特质和自定义main方法,不符合Scala程序入口规范,可能导致业务逻辑未实际执行,看起来为无响应状态。
对应解决方案
1. 修正JDBC配置与代码逻辑
补全JDBC URL的必填参数,修正表名配置,调整程序入口:
import org.apache.spark.sql.SparkSession import java.util.Properties // 要么去掉App特质保留main方法,要么保留App特质去掉main方法包裹 object MySQLSample { def main(args: Array[String]): Unit = { val spark = SparkSession .builder() .appName("FiboConn") .getOrCreate() // 补全数据库名、SSL、时区、超时参数 val url = "jdbc:mysql://host:3306/dbo?useSSL=false&serverTimezone=Asia/Shanghai&connectTimeout=30000&socketTimeout=60000" // table参数填写实际要查询的表名,而非数据库名 val table = "Job" val properties = new Properties() properties.put("user", "你的实际用户名") properties.put("password", "你的实际密码") // 明确指定驱动类 properties.put("driver", "com.mysql.cj.jdbc.Driver") val mySQLDF = spark.read.jdbc(url, table, properties) mySQLDF.show(100) } }
基础JDBC连接测试代码同步修正配置:
import java.sql.DriverManager val jdbcUrl = "jdbc:mysql://host:3306/dbo?useSSL=false&serverTimezone=Asia/Shanghai&connectTimeout=30000" val connection = DriverManager.getConnection(jdbcUrl, jdbcUsername, jdbcPassword)
2. 匹配JDBC驱动版本
- 若MySQL服务端版本为5.7及以下,使用5.x版本的MySQL JDBC驱动,驱动类填写
com.mysql.jdbc.Driver - 若MySQL服务端版本为8.0及以上,使用8.x版本的MySQL JDBC驱动,驱动类填写
com.mysql.cj.jdbc.Driver - 提前确认Databricks集群已预装对应版本的驱动,未预装的话需手动上传驱动jar包绑定到集群。
3. 解决分布式网络权限问题
如果不需要分布式拉取数据,强制所有JDBC请求走Driver节点,和PyMySQL执行逻辑保持一致:
val mySQLDF = spark.read.format("jdbc") .option("url", url) .option("dbtable", "Job") .option("user", "你的实际用户名") .option("password", "你的实际密码") .option("driver", "com.mysql.cj.jdbc.Driver") // 强制单分区,所有请求走Driver .option("numPartitions", 1) .load()
如果需要分布式查询,联系运维开放所有Spark Worker节点到MySQL服务器3306端口的出口访问权限。
内容的提问来源于stack exchange,提问作者Loren
相关产品推荐
相关产品推荐

