我一直在接收和存储未压缩的 JSON对象的多个提要,将分区到今天,并将其存储到亚马逊S3桶的不同位置(hive样式:s3://bucket/object=<object>/year=<year>/month=<month>/day=<day>/object_001.json),并计划使用AWS递增批处理数据并将其加载到Parquet数据湖:
这种设计模式和体系结构似乎是一种非常安全的方法,因为它得到了许多AWS博客、这里和那里的支持。
我有一个爬行器配置如下:
{
"Name": "my-json-crawler",
"Targets": {
"CatalogTargets": [
{
"DatabaseName": "my-json-db",
"Tables": [
"some-partitionned-json-in-s3-1",
"some-partitionned-json-in-s3-2",
...
]
}
]
},
"SchemaChangePolicy": {
"UpdateBehavior": "UPDATE_IN_DATABASE",
"DeleteBehavior": "LOG"
},
"Configuration": "{\"Version\":1.0,\"Grouping\":{\"TableGroupingPolicy\":\"CombineCompatibleSchemas\"}}"
}每个表都是“手动”初始化的:
{
"Name": "some-partitionned-json-in-s3-1",
"DatabaseName": "my-json-db",
"StorageDescriptor": {
"Columns": [] # i'd like the crawler to figure this out on his first crawl,
"Location": "s3://bucket/object=some-partitionned-json-in-s3-1/",
"PartitionKeys": [
{
"Name": "year",
"Type": "string"
},
{
"Name": "month",
"Type": "string"
},
{
"Name": "day",
"Type": "string"
}
],
"TableType": "EXTERNAL_TABLE"
}
}正如预期的那样,爬虫的第一次运行需要一个小时左右的时间,但是它成功地计算出了表模式和现有分区。然而,从那时起,重新运行爬虫所花费的时间与第一次爬行所花费的时间完全相同,如果不是更长的话;这使我相信爬虫不仅在爬行新的文件/分区,而且每次都会重新搜索所有的S3位置。
请注意,两个爬行之间的新文件增量非常小(每次期望的新文件很少)。
AWS文件建议运行多个爬虫,但我不相信这将从长远来看解决我的问题。我还考虑在每次运行后更新爬虫排除模式,但是接下来我会发现使用crawler比通过一些Lambda boto3魔术手动更新表分区的优势太少了。
我是不是漏掉了什么?也许我会误解爬虫更新现有数据目录的选项,而不是直接抓取数据存储?
有什么改进我的数据编目的建议吗?考虑到在Glue表中索引这些JSON文件对我来说仅仅是必要的,因为我希望Glue作业使用书签。
谢谢!
发布于 2022-02-16 10:19:59
在这个尚未回答的问题上,我仍然遇到了一些问题,所以我想分享一个我当时认为足够的解决方案:我最终没有使用爬虫,在所有的中,我都是在逐步更新我的Glue表。
使用S3 Events / S3 Api通过CloudTrail / S3事件桥通知(pick one)调用,最终编写了一个lambda,其中弹出了雅典娜上的ALTER TABLE ADD PARTITION DDL查询,使用新创建的分区(基于S3键前缀)更新了已经存在的Glue表。在我看来,这是一种非常直截了当、代码较低的维护Glue表的方法;唯一的缺点是处理服务节流(包括Lambda和Athena),以及查询失败,以避免在过程中丢失任何数据。
但是,这个解决方案扩展得很好,因为每个帐户的并行DDL查询是一个软限制配额,随着您需要更新越来越多的表,这个限额可以增加;而且对于非时间关键工作流也很有效。
如果将S3写入到Glue表S3分区(在此特定实现中每个Glue表分区一个文件是理想的),则工作得更好,方法是对数据进行批处理,例如使用DeliveryStream。
发布于 2022-10-24 02:12:28
AWS Glue Crawler现在本机支持Amazon S3事件通知,以解决这个问题。
见博客文章。
https://stackoverflow.com/questions/60649897
复制相似问题