我正在使用Spark生成拼花文件(通过setid
分区,使用Snappy压缩),并将它们存储在HDFS位置。
df.coalesce(1).write.partitionBy("SetId").
mode(SaveMode.Overwrite).
format("parquet").
option("header","true").
save(args(1))
拼花数据文件存储在/some-hdfs-path/testsp
下
然后为其创建配置单元表,如下所示:
CREATE EXTERNAL TABLE DimCompany(
CompanyCode string,
CompanyShortName string,
CompanyDescription string,
BusinessDate string,
PeriodTypeInd string,
IrisDuplicateFlag int,
GenTimestamp timestamp
) partitioned by (SetId int)
STORED AS PARQUET LOCATION '/some-hdfs-path/testsp'
TBLPROPERTIES ('skip.header.line.count'='1','parquet.compress'='snappy');
msck repair table dimcompany;
spark.sql("SET spark.sql.hive.convertMetastoreParquet=false")
问题是分区列setid
使用了大写字母。
由于配置单元将其列名转换为小写,因此分区列存储为setid
而不是setid
。因此,当Hive在区分大小写的数据存储区中搜索分区/文件夹时,它会查找setid=some_value
,但没有找到任何东西,因为数据文件夹的格式为setid=some_value
。
为此,请将setid
转换为小写或snake_case。您可以通过对数据帧中的列进行别名来使用此功能:
df.select(
... {{ your other_columns }} ...,
col("SetId").alias("set_id")
)
SET hive.mapred.supports.subdirectories=TRUE;
SET mapred.input.dir.recursive=TRUE;
msck repair table <your_schema.your_table>;
先声明一下,这不是Hadoop的生产环境。这是一个我们测试工作流的单节点环境
当使用外部配置单元表时,是否有一种方法可以删除目录中的数据,但通过查询保留分区。请注意,我不想删除表并重新创建它。我只想清空底层文件夹并重新启动一个进程。我的表很大,按年、月、日期和小时划分分区,手动重新创建分区需要大量时间。 谢谢
我有一个map reduce作业,它已经使用配置单元分区命名约定将记录写入hdfs。 如 有没有一种方法可以让hive自动识别分区(不需要执行插入查询)?
更新:恰恰相反。实际上,我们的表非常大,就像3个TB有2000个分区。3TB/256MB实际上会达到11720,但我们的分区数量与表的物理分区数量完全相同。我只想了解任务是如何在数据量上生成的。