如何在 S3 中查询异构 JSON 数据?
Posted
技术标签:
【中文标题】如何在 S3 中查询异构 JSON 数据?【英文标题】:How do I query heterogeneous JSON data in S3? 【发布时间】:2018-05-08 22:16:07 【问题描述】:我们有一个 Amazon S3 存储桶,其中包含大约一百万个 JSON 文件,每个压缩文件大约 500KB。这些文件由 AWS Kinesis Firehose 放在那里,每 5 分钟写入一个新文件。这些文件都描述了类似的事件,因此在逻辑上都是相同的,并且都是有效的 JSON,但具有不同的结构/层次结构。它们的格式和行尾也不一致:一些对象在一行上,一些在多行上,有时一个对象的结尾与另一个对象的开头在同一行(即)。
我们需要解析/查询/分解这些对象,然后将结果导入我们的本地数据仓库 SQL Server 数据库。
Amazon Athena 无法处理不一致的间距/结构。我想创建一个 Lambda 函数来清理间距,但这仍然会留下不同结构的问题。由于文件是由 Kinesis 放置的,这迫使您将文件放在按年、月、日和小时嵌套的文件夹中,因此我们每年必须创建数千个分区。 Athena 中的分区数量限制并不为人所知,但研究表明,如果我们每小时创建一个分区,我们将很快耗尽这个限制。
我研究过先将数据注入 Redshift,然后再将其拉下。 Amazon Redshift 外部表可以处理间距问题,但无法处理几乎所有这些文件都有的嵌套 JSON。 COPY
命令可以处理嵌套的 JSON,但需要我们事先知道 JSON 结构,并且不允许我们访问文件名,这是我们完整导入所需的(这是我们获取日期的唯一方法) .总的来说,Redshift 和 Athena 有同样的问题:不一致的结构使得定义模式变得困难。
我曾研究过使用 AWS Glue 等工具,但它们只是移动数据,无法将数据移动到我们的本地服务器中,因此我们必须找到某种中介,这会增加成本、延迟、和维护开销。
我试过去掉中间人,使用 ZappySys 的 S3 JSON SSIS 任务直接拉取文件并将它们聚合到一个 SSIS 包中,但它无法处理间距问题或结构不一致的问题。
我不能成为第一个遇到这个问题的人,但我只是不停地旋转。
【问题讨论】:
为什么首先要向 Kinesis Firehose 发送不一致的数据?您能否改为将数据发送到几个不同的 Firehose,以便每个 Firehose 接收到您可以查询的一致数据? @JohnRotenstein 我无法控制进入 S3 的数据。我正在与客户合作以使数据更加一致,但这将是一个不断变化的目标,并且仍然给我留下了如何处理现有数据的问题。 【参考方案1】:Rumble 是一个开源 (Apache 2.0) 引擎,允许您使用 JSONiq 查询语言直接查询存储在 S3 上的 JSON(特别是 JSON Lines 文件),而无需将其移动到其他任何地方或将其导入任何数据存储。在内部,它使用 Spark 和 DataFrames。
它已在超过 200 亿个对象 (10+ TB) 的集合上成功测试,如果数据是嵌套和异构的(缺少字段、额外字段、同一字段中的不同类型等),它也可以无缝工作。它还使用 Amazon EMR 集群进行了测试。
更新:Rumble 还适用于 Parquet、CSV、ROOT、AVRO、文本和 SVM,以及 HDFS、S3 和 Azure。
【讨论】:
【参考方案2】:我可能会建议两种解决方案
-
我相信 MongoDB/DynamoDB/Cassandra 擅长处理异构 JSON 结构。我不确定您的 JSON 中的不一致,但只要它是有效的 JSON,我相信它应该可以在上述数据库之一中摄取。如果可能,请提供示例 JSON。但这些工具各有优缺点。这些 No SQL 的数据建模与传统 SQL 完全不同。
我不确定为什么您的 Lambda 无法进行清理。我相信当存储桶中发生 S3 PUT 时,您会尝试调用 Lambda。除非涉及复杂的过程,否则这应该能够清理 JSON。
除非 JSON 格式正确,否则任何工具都无法完美处理它,我相信除了 Athena 或 Spectrum,MongoDB/DyanoDB/Cassandra 更适合此用例
如果您能分享您在创建大量分区时所面临的限制,那会很棒吗?
【讨论】:
我更新了问题以澄清分区和格式。 我正在使用 MongoDB 进行我需要的转换,并且运行良好。谢谢! 谢谢,很高兴听到。 Mongo 有设置集群的麻烦。如果您在 AWS 中,请尝试 DynamoDB,这样您就无需维护任何基础设施;但是 DynamoDB 不具备 Mongo 支持的所有功能(嵌入式数据结构),并且具有更好的可扩展性和易于维护性 该公司已经在使用 MLAB 来使用 Mongo 作为服务,所以我能够只是捎带它。以上是关于如何在 S3 中查询异构 JSON 数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 EMR 上的 HiveQL 将 DynamoDB 上的 Map 数据类型列导出到具有 JSON 数据类型的 S3?
AWS:如何修复 S3 事件用“+”在 json 中登录对象键名替换空格