故障排查:开启了Databricks的Table Access Controler之后,Python脚本无法访问外部的数据库了
分类: 故障排查 ◆ 标签: #Databricks #大数据 ◆ 发布于: 2023-08-07 22:14:07
最近遇到一个案例:起初我们是想在Databricks
里通过pyodbc
访问访问外部的数据,这个简单,写一个脚本,然后把这个脚本放置到集群的初始化脚本里,安装必要的库就行了。脚本如下:
#!/bin/sh curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list sudo apt-get update sudo ACCEPT_EULA=Y apt-get install msodbcsql17 pip install pyodbc
写完保存该脚本之后,上传到DBFS
里,如下图:
上传成功后,在创建集群的时候或者编辑集群按照如下的方式配置初始化脚本:
启动集群之后,创建一个Notebook
, 运行如下的Python
脚本:
import pyodbc conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};' 'SERVER={ServerName};' 'DATABASE={dbname};UID={username};' 'PWD={Password}') cursor = conn.cursor() cursor.execute("SELECT @@version;") row = cursor.fetchone() while row: print(row[0]) row = cursor.fetchone() conn.close()
运行该notebook
可以很完美的得到结果。
继续测试,从Databricks
菜单里启用Table Access Control
Admin Console
:
重启集群,再次运行该
notebook
,发现问题来了:
刚才还好好的notebook
现在报错了:
OperationalError: ('HYT00', '[HYT00] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
开始排查,首先想到的肯定是因为开启了Table access control
, 为了验证这个问题,关闭Table access Control
, 测试成功,打开,失败。
所以问题就是出在Table Access control
上,根据错误的提示,首先想到是不是网络不通了。
在Notebook
里新建一个cell
, 运行:
%sh nc -zv {you Database address} 1433
发现还是真是连不通了,赶紧翻文档,找到文档说明:
https://learn.microsoft.com/en-us/azure/databricks/security/access-control/table-acls/table-acl
果然找到了问题所在,所以需要在集群里添加一个配置:
spark.databricks.pyspark.iptable.outbound.whitelisted.ports 1433
如下图:
重启集群,然后再次使用如下的脚本测试连通性:
%sh nc -zv {you Database address} 1433
这次发现果然端口通了。
再次运行notebook
, 还是报错,同样的错误:
OperationalError: ('HYT00', '[HYT00] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
头疼!明明端口是通的,为什么又报错了?想起了另外一件事:会不会是外部的Azure SQL DB
的问题。记起来了Azure SQL DB
有提供三种连接方式:
default
proxy
redirect
打开Azure SQL DB Server
的Networking
,可以看到:
如果选择模式redirect
,SQL DB的连接实际上只有第一次连接走1433
,后面的存取直接和instance
通讯了,用了其他的端口。所以我们需要选择Proxy
模式,永远都使用1433
的默认端口。
重新设定了Azure SQL DB
的连接方式,终于连接成功了!