Spark 2.2.0查询1900列Avro格式Hive表遇元存储连接丢失问题求助
问题分析与实战解决方案
咱们先把核心矛盾点理清楚:
- 1900列的Avro Hive表
table1在Hive里查得好好的,但Spark SQL一查就报metastore client lost connection. Attempting to reconnect - 同格式但只有130列的
table2,Hive和Spark都能正常查询 - 更奇怪的是,
table1的HDFS路径下看不到数据,但Hive却能查出数据
下面是我遇到类似问题时的排查思路和解决办法:
1. 大列数导致Spark metastore元数据传输超时
Spark的metastore客户端默认配置对**超大量列(1900列)**的元数据传输支持有限,而Hive本身的metastore在处理大元数据时阈值更高。当Spark请求table1的元数据时,数据量太大直接把连接撑超时了,就触发了重连报错。
解决办法:
在提交Spark作业的时候,加上这些配置,给metastore客户端足够的缓冲时间和资源:
spark-submit \ --conf hive.metastore.client.socket.timeout=300s \ --conf hive.metastore.client.connect.retry.delay=5s \ --conf hive.metastore.client.capacity=10 \ # 其他作业参数...
解释下:增大socket超时时间让Spark能等完元数据传输,调整重试延迟避免频繁重连,提升连接池容量应对大请求。
2. Hive表的存储路径藏了猫腻(分区/外部表坑)
你说table1的HDFS路径下没数据但Hive能查,这十有八九是这两种情况:
- 这是个分区表,你看的是表的根路径,实际数据都存在各个分区的子目录里
- 或者是外部表,Hive元数据里记录的实际数据路径和你手动查看的路径根本不一致
Spark读分区表的时候,得从metastore拿所有分区的元数据,再加上1900列的schema,双重压力直接把连接搞崩了。
解决步骤:
- 先在Hive里跑
DESCRIBE FORMATTED table1;,重点看Location字段确认真实数据路径,再看Partitioned是不是YES - 如果是分区表,再跑
SHOW PARTITIONS table1;看看分区情况,去对应的分区子目录里找数据 - 如果是外部表路径配错了,要么在Hive里修正表的存储路径,要么直接在Spark里指定正确路径读:
SELECT * FROM avro.`hdfs://真实的table1数据路径`
3. 超复杂Avro schema把Spark解析器搞懵了
1900列的Avro schema太庞大了,Spark的Avro解析器在处理这种级别的schema时,可能因为内存不够或者解析时间太长,间接导致metastore连接超时。
解决办法:
- 给Spark Driver加内存,比如设置
--driver-memory 8g(根据你的集群资源调整,别超了),给schema解析足够的内存空间 - 别啥列都查!尽量只查你需要的列,比如:
这样Spark只需要拉取指定列的元数据,数据量直接砍到原来的几分之一,连接超时的问题自然就缓解了。SELECT col_id, col_name, col_create_time FROM table1
4. Hive Metastore本身扛不住大请求
如果你的Hive metastore服务本身资源不够,比如内存小、CPU弱,处理table1这种大表的元数据请求时响应慢得离谱,也会导致Spark客户端连接超时。
建议操作:
- 去看metastore的日志,搜搜有没有慢查询、内存溢出的报错
- 调整metastore的JVM参数,比如把堆内存调到
-Xmx16g(根据服务器配置来),提升它处理大元数据的能力 - 检查metastore所在节点的网络带宽,别因为网络拥堵导致元数据传半天传不过来
内容的提问来源于stack exchange,提问作者Avinash
相关产品推荐
相关产品推荐

