Spark连接Vertica可获Schema与计数但无法读取数据求助
这问题我之前处理过类似的场景,咱们从几个核心角度拆解原因,再对应给出解决办法:
1. 版本不匹配是首要嫌疑
你的Vertica服务器版本是09.02.0104,但使用的Vertica JDBC和Spark Connector都是09.01.0100版本。虽然同属9.x系列,但Vertica的JDBC驱动和Spark Connector对服务器版本的兼容性要求很严格——尤其是数据读取阶段(show()触发的分布式数据拉取),9.02版本的服务器协议可能有更新,9.01的客户端jar无法适配;而printSchema()和count()这类操作仅在Driver节点完成元数据查询或简单统计,不需要Executor参与,所以能正常执行。
解决办法:
- 下载和Vertica服务器版本完全一致的
vertica-jdbc-9.02.0104.jar和vertica-9.0.2_spark2.1_scala2.11.jar(匹配你的Spark2.1、Scala2.11环境),替换当前的9.01版本jar包,重启spark-shell重试。
2. Executor节点网络未打通(分布式场景核心坑)
你提到从EMR主机(Driver节点)能telnet通Vertica,但Spark执行show()时,是由Executor节点发起数据连接请求的。如果Vertica的防火墙/安全组只开放了Driver节点的IP,没有放行EMR集群所有Executor节点的IP,就会出现连接超时的错误——这是分布式大数据场景中非常常见的网络问题。
验证与解决:
- 登录到EMR的任意一个Executor节点,执行
telnent verticaHost port,确认是否能连通。如果不通,说明网络存在问题。 - 调整Vertica的安全组/防火墙规则,添加EMR集群所有节点的IP段(或单个Executor IP)到允许访问的列表中;如果是VPC环境,确认EMR和Vertica所在VPC有对等连接或路由打通。
3. 连接参数配置错误
你当前的db参数格式有问题:option("db", "DataBase?ssl=true"),这种写法可能导致Connector无法正确解析数据库名称和SSL参数。另外,SSL参数需要单独配置,不要嵌入到db名称里。
修正后的连接代码:
val source = spark.read.format("com.vertica.spark.datasource.DefaultSource") .option("host", "verticaHost") .option("port", "port") .option("db", "DataBase") // 单独指定数据库名 .option("ssl", "true") // 独立配置SSL .option("dbschema", "Schema") // 注意你原代码拼写错了Schemna,需修正! .option("user", "user") .option("password", "password") .option("table", "table") .option("numPartitions", "1") .option("queryTimeout", "500") .load()
另外,原代码里的dbschema拼写错误(写成了Schemna),虽然printSchema()能执行,但可能在数据读取时引发隐性问题,建议先修正。
4. 关于query参数的额外说明
你提到添加option("query", "select * from schema.table limit 100")后,count()返回全表计数而非100。这是Vertica Spark Connector的特性:count()操作会被优化为直接执行select count(*) from table,忽略你指定的query参数。如果要统计100条数据的数量,应该用:
source.limit(100).count()
验证步骤建议
- 先修正版本和参数拼写问题,重启spark-shell测试
show(); - 如果还是失败,检查Executor节点的网络连通性;
- 若网络没问题,尝试添加
option("useServerPrepStmts", "false")参数,关闭预编译语句,部分场景下能解决连接超时问题。
内容的提问来源于stack exchange,提问作者g1_




