我正在尝试将表定义从一个 Hive 元存储迁移到另一个。
源集群具有:
- 火花 1.6.0
- Hive 1.1.0 (cdh)
- 高密度文件系统
目标集群是一个 EMR 集群,具有:
- 火花 2.1.1
- 蜂巢 2.1.1
- S3
要迁移表,我执行了以下操作:
- 将数据从 HDFS 复制到 S3
SHOW CREATE TABLE my_table;
在源集群中运行- 修改返回的创建查询——
LOCATION
从HDFS路径改为S3路径 - 在目标集群的 Hive 上运行修改后的查询
- 运行
SELECT * FROM my_table;
。这将返回 0 行(预期) - 运行
MSCK REPAIR TABLE my_table;
。这会按预期通过并在元存储中注册分区。 - 运行
SELECT * FROM my_table LIMIT 10;
- 10 行返回正确的值 - 在目标集群上,从配置为使用 Hive Metastore 的 Spark 运行以下代码:
spark.sql("SELECT * FROM my_table limit 10").show()
- 这将返回空值!
Spark SQL 查询返回的结果包含所有正确的列和正确的行数,但所有值均为空。
为了让 Spark 正确加载值,我可以将以下属性添加到TBLPROPERTIES
创建查询的部分:
'spark.sql.partitionProvider'='catalog',
'spark.sql.sources.provider'='org.apache.spark.sql.parquet',
'spark.sql.sources.schema.numPartCols'='<partition-count>',
'spark.sql.sources.schema.numParts'='1',
'spark.sql.sources.schema.part.0'='<json-schema as seen by spark>'
'spark.sql.sources.schema.partCol.0'='<partition name 1>',
'spark.sql.sources.schema.partCol.1'='<partition name 2>',
...
这个问题的另一面是,在源集群中,Spark 读取表值没有任何问题,也没有额外的TBLPROPERTIES
.
为什么会这样?如何修复?