例如,一个具有以下结构的s3存储桶,其文件格式为 francescototti_yyyy_mm_dd_hh.csv.gz:
例如:
francescototti_2019_05_01_00.csv.gz,
francescototti_2019_05_01_01.csv.gz,
francescototti_2019_05_01_02.csv.gz,
.....
francescototti_2019_05_01_23.csv.gz,
francescototti_2019_05_02_00.csv.gz
每个小时文件大约30 MB。我希望最终的配置单元表按存储为orc文件的日期进行分区。
做到这一点的最佳方法是什么?我想了几种方法,可能是以下一种。
一个自动脚本,用于获取每小时的小时文件并将其移动到s3存储桶中的相应的day文件夹中。在此新结构化的s3存储桶上创建分区的外部表。
在原始s3位置的顶部有一个外部配置单元表,并创建了一个附加的已分区配置单元表,该表已从原始表插入。
每种优点/缺点是什么?还有其他建议吗?
答案 0 :(得分:1)
第一个选项 :(一种自动脚本,用于获取每小时的小时文件并将其移动到s3存储桶中的相应day文件夹中。在此新结构化的s3存储桶上创建分区的外部表)比在原始s3位置顶部构建文件要好,因为原始位置包含太多文件,并且查询将运行缓慢,因为即使您按INPUT__FILE__NAME虚拟列进行过滤,它也会列出所有文件如果您收到其中的新文件,情况将会变得更糟。
如果文件太多,例如原始文件夹中有数百个文件,并且文件没有增长,那么我会选择option2。
选项一的可能弊端是删除文件并反复读取/列出文件夹后最终出现一致性问题。在删除大量文件(一次删除数千个文件)之后,您肯定会在接下来的大约1个小时内遇到最终的一致性问题(虚拟文件)。 如果您不想一次删除太多文件。看来您不是,您一次将移动24个文件,然后很有可能不会在s3中遇到最终的一致性问题。 另一个缺点是文件移动成本高。但是总比读取/列出同一文件夹中的太多文件更好。
因此,选项一看起来更好。
其他建议: 重写上游进程,以便将文件写入日常文件夹。这是最好的选择。在这种情况下,您可以在s3顶级位置之上构建表,并且每天仅添加每日分区。分区修剪将正常工作,您无需移动文件,也不会出现s3不一致的问题。
答案 1 :(得分:1)
您可以将Amazon S3事件配置为在Amazon S3存储桶中创建对象时自动触发AWS Lambda函数。
此Lambda函数可以读取文件名(密钥)并将对象移动到另一个目录(实际上,它将复制+删除对象)。
这样,对象一被创建就被移动到所需的位置。不需要批处理作业。
但是,这不会更改文件的格式。可以使用 Amazon Athena 将内容转换为Convert to Columnar Formats。这有点棘手,因为您需要指定源和目的地。