Databricks JDBC 连接有效,但查询失败

Posted

技术标签:

【中文标题】Databricks JDBC 连接有效,但查询失败【英文标题】:Databricks JDBC Connections works but query fails 【发布时间】:2021-06-09 12:11:22 【问题描述】:

我正在尝试通过 Azure Databricks 建立与 SQL Server 数据库的连接。虽然这里有很多问题attempting to alleviate issues,但我还没有找到适合我的解决方案。

我能够连接,至少看起来是因为 DataFrame (spark) 对象从我的数据库表中读取了确切的模式,但在尝试查看数据(display(df)df.show())时它会引发连接错误。

这是我的连接方式:

jdbcUrl = "jdbc:sqlserver://:;database=".format(jdbcHostname, jdbcPort, jdbcDatabase)

connectionProperties = 
  'user': jdbcUsername,
  'password': jdbcPassword,
  "driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver"


pushdown_query = "(select * from persons where personid = 3040) Person"
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)
display(df)

我可以看到 df 对象,它正确识别了表中的所有 47 个字段(见下图),但 display(df) 抛出以下错误:

SQLServerException: The TCP/IP connection to the host hornets-sql.westus.cloudapp.azure.com, port 1433 has failed. Error: "connect timed out. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".

【问题讨论】:

【参考方案1】:

默认情况下,SQL Server 启用了防火墙,并且不允许来自任意 IP 的访问。在您的情况下,您可能在防火墙中允许驱动程序节点 - 这就是您获得表模式的原因,但读取本身发生在防火墙上可能未启用的工作节点上,并且读取失败。

您可以尝试通过以下方式解决它:

    将所有工作节点的公共 IP 添加到 SQL Server 的防火墙中 或通过将private link/endpoint for Azure SQL 配置到您的 VNet 中 或使用 Azure 服务的服务端点

Databrick 的blog post 很好地涵盖了最后两项。

【讨论】:

以上是关于Databricks JDBC 连接有效,但查询失败的主要内容,如果未能解决你的问题,请参考以下文章

通过 Simba JDBC 的 Databricks Spark 连接问题

连接到 postgresql:dbserver db 通过 JDBC 连接到 Databricks 时连接被拒绝

无法使用 jdbc 和 spark 连接器从 databricks 集群连接到 Azure 数据库 for MySQL 服务器

使用 Databricks 连接到 AWS Postgres

如何在 Azure Databricks 中使用 JDBC 从 PostgreSQL 读取表数据?

在 Python 中读取 SQL 文件以通过 databricks 对 JDBC 运行