Hive 使用 HIVE CONCATENATE 合并所有分区

suh*_*has 3 bash hadoop hive bigdata hdfs

我有一个 hive 外部表,它在源系统上分区,这意味着数据将来自多个源系统。数据目录结构为:

/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem1

/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem2

/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystem3

...

/app/hadoop/MyProject/SchemaName/TableName/PartitionColumn=SoruceSystemN
Run Code Online (Sandbox Code Playgroud)

并且进入SourceSystem文件夹的所有数据都是流数据,所以我们在每个源系统下都有很多文件:)。

我正在考虑每天合并所有这些文件,例如:SourceSystem1 中的所有文件将被合并,合并后的文件保留在SoruceSystem1文件夹中,依此类推。

通常: alter table schema.table PARTITION(PartitionColumn={SourceSystemName}) CONCATENATE;当只有一个文件夹时效果很好,但我需要一次性为所有文件夹执行此操作。

解决方法是编写一个shell 脚本来遍历所有分区,然后对每个源系统名称重复此语句,但我正在寻找开箱即用的东西来解决此用例。

非常感谢这里的任何帮助。

kfk*_*ili 7

重要- 如果您的表架构已经演变(例如添加了新列)但仍包含使用旧架构的文件。CONCATENATE可能会默默地删除这些文件。请参阅错误报告。如果表是非托管的,解决方法已使此操作失败,并最终在 Hive 3.0.0 中修复。

既然已经解决了,我们需要分两步完成。

首先,我们获取有问题的表中的分区,并将它们写入一个文本文件,以便我们稍后参考。

beeline --showHeader=false --outputformat=tsv2 --silent=true -e "SHOW PARTITIONS database.table" > found_partitions.txt
Run Code Online (Sandbox Code Playgroud)

这将写入没有标题或框架的找到的分区列表。

接下来,我们需要遍历分区列表,part1=some/part2=thing用逗号交换潜在的分区分隔符 ( ),因为前者不是合法的 Hive 字符。如果您的表中只有一个分区结构,这将不起作用。我们还假设您的所有分区都是字符串,并且需要用引号括起来。

#!/bin/bash

for line in `cat found_partitions.txt`; do
    echo "the next partition is $line"
    partition=`(echo $line | sed -e 's/\//,/g' -e "s/=/='/g" -e "s/,/',/g")`\'
    beeline -e "ALTER TABLE database.table PARTITION($partition) CONCATENATE" 
done
Run Code Online (Sandbox Code Playgroud)

注意:您可能需要为 beeline 设置一些配置才能为您工作。可能想为此设置别名。

 beeline -u "jdbc:hive2://<SERVER>:<PORT>/;serviceDiscoveryMode=<zooKeeper>;zooKeeperNamespace=<hiveserver2>;principal=<USER>;transportMode=<SOMETHING>;httpPath=<SOMETHING>"
Run Code Online (Sandbox Code Playgroud)