hive使用hive concatenate合并所有分区

f87krz0w  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(1484)

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

/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

所有进入sourcesystem文件夹的数据都是流数据,因此我们在每个源系统下都会得到很多文件:)。
我正在考虑每天合并一次所有这些文件,例如:sourcesystem1中的所有文件都将被合并,合并后的文件将保留在sorucesystem1文件夹中,其他文件也是如此。
通常: alter table schema.table PARTITION(PartitionColumn={SourceSystemName}) CONCATENATE; 当只有一个文件夹时效果很好,但我需要一次性为所有文件夹执行此操作。
解决方法是编写一个shell脚本在所有分区中循环,然后对每个源系统名称重复此语句,但我正在寻找一些现成的方法来解决此用例。
非常感谢您的帮助。

jdgnovmf

jdgnovmf1#

所以我们需要分两步来做。
首先,我们获取相关表中的分区,并将它们写入一个文本文件中,以便稍后引用。

beeline --showHeader=false --outputformat=tsv2 --silent=true -e "show partitions database.table" > found_partitions.txt

这将写入找到的没有头或帧的分区的列表。
接下来,我们需要遍历分区列表,交换潜在的分区分隔符( 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

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

beeline -u "jdbc:hive2://<SERVER>:<PORT>/;serviceDiscoveryMode=<zooKeeper>;zooKeeperNamespace=<hiveserver2>;principal=<USER>;transportMode=<SOMETHING>;httpPath=<SOMETHING>"

相关问题