使用 AWS 使用大量第三方 API 数据的最佳策略?
Best strategy to consume large amounts of third-party API data using AWS?
我对 AWS 比较陌生,正在研究最能支持我们正在开发的服务的特定业务需求的策略。
我们面临的挑战有:
- 我们需要从第三方提取一个非常大的数据集(数十万条记录)API,它以最大 50 组的形式提供分页记录;
- 我们需要为每个导入的记录分配两个唯一的内部键;
- 我们需要通过定期调用更新和新记录来更新导入的记录;和
- 我们将及时添加来自其他来源的记录 - 并且需要协调(匹配、复制)来自多个来源的数据。
我们的目标是将这些数据与我们的主数据库分开,以便我们可以根据需要独立管理和查询它。因此,我们一直在考虑的策略是:
- 在递归 lambda 函数中进行 API 调用(由于分页);
- 将调用结果作为单个或多个 json 文件存储在 S3 存储桶中;
- 将 S3 数据拉入非关系数据库。
我们这里遇到了一些问题:
- 鉴于初始导入需要几个小时,我们的 lambda 将在 15 分钟(硬限制)时超时;
- 将我们自己的唯一密钥分配给传入数据的最佳方法是什么(理想情况下,应该通过获取传入数据并根据我们的需要重新格式化来生成一个密钥);和
- 使用来源或第三方的更新信息更新这些记录的最佳策略是什么?
不确定是否应将其分解为三个问题 - 但这似乎是提供完整上下文的最佳方式。
关于数据导入,您可以使用 AWS Step Functions 构建一个循环来顺序检索数据。看看这个博客 post:https://read.acloud.guru/processing-an-arbitrary-number-of-jobs-with-aws-step-functions-c185c2d2608
你的另外两个问题(分配键和随后的充实和更新)需要更多的上下文和世界,如果 post 作为单独的问题进行编辑可能是最好的。
一些评论。
We need to pull in a very large data set (hundreds of thousands of records) from a third-party API, which delivers paginated records in max groups of 50;
这意味着大约 "thousands" 次调用第三方 API。在你提到的问题的其他地方 "several hours"。使用 API 的提供者可以加载此负载吗?只有一件事要考虑,你的情况是你没有。
Making the API calls in a recursive lambda function (due to pagination);
非常小心 递归 Lambda 函数调用,即异步调用自身的 Lambda 函数。可能会发生这样的情况,由于一个错误,Lambda 永远不会停止调用自己,然后您会陷入 Lambda 调用的无限循环并增加费用……它可以停止,但它是一个 PITA。
Storing the results of the call in an S3 bucket as a single - or multiple - json files;
如果您想使用 S3,我可能建议将聚合的数据存储到更少的文件中。您没有提到每条数据的大小,但是大量的小文件对于 S3 来说并不理想。另一方面,只有一个巨大的(例如,几十或几百 GB 或更多)对于以后 processing 来说并不理想(即使 S3 可以毫无问题地处理它) .
我建议您调查两件事:
- Step Functions。
由于您需要处理第 3 方的分页 API,您可以在 Step Functions 中定义一个状态机来为您调用 Lambda。 Lambda 会做它的事情(下载一堆记录,将它们存储在 某个地方 )并且 return 或者下载记录的数量,或者待处理记录的数量,类似的东西.然后 Step Functions 的状态机将负责决定是否再次调用下载 Lambda 的逻辑(甚至可能使用基于先前调用的值 return 的参数)或者是否完成。
这样,您就可以很好地分离关注点:一个超级特定的 Lambda 函数,它只摄取东西;并且您将分页逻辑分开(甚至可能 "parallelism" 或 "timing" 逻辑,如果出于某种原因您被要求 "slow down" 您对第 3 方的调用 API) .
- Kinesis Firehose
Kinesis Firehose 是一种流式数据管道。基本上,您配置一个 firehose 流来为您聚合记录并转储它们 "somewhere"(例如,S3 是一个有效目标)。您可以选择聚合方式(例如时间、数据量)。您甚至可以配置 Firehose 以调用 Lambda 函数在存储之前为您转换每条记录(例如,您可以在此处添加您的 2 个唯一标识符)。
我对 AWS 比较陌生,正在研究最能支持我们正在开发的服务的特定业务需求的策略。
我们面临的挑战有:
- 我们需要从第三方提取一个非常大的数据集(数十万条记录)API,它以最大 50 组的形式提供分页记录;
- 我们需要为每个导入的记录分配两个唯一的内部键;
- 我们需要通过定期调用更新和新记录来更新导入的记录;和
- 我们将及时添加来自其他来源的记录 - 并且需要协调(匹配、复制)来自多个来源的数据。
我们的目标是将这些数据与我们的主数据库分开,以便我们可以根据需要独立管理和查询它。因此,我们一直在考虑的策略是:
- 在递归 lambda 函数中进行 API 调用(由于分页);
- 将调用结果作为单个或多个 json 文件存储在 S3 存储桶中;
- 将 S3 数据拉入非关系数据库。
我们这里遇到了一些问题:
- 鉴于初始导入需要几个小时,我们的 lambda 将在 15 分钟(硬限制)时超时;
- 将我们自己的唯一密钥分配给传入数据的最佳方法是什么(理想情况下,应该通过获取传入数据并根据我们的需要重新格式化来生成一个密钥);和
- 使用来源或第三方的更新信息更新这些记录的最佳策略是什么?
不确定是否应将其分解为三个问题 - 但这似乎是提供完整上下文的最佳方式。
关于数据导入,您可以使用 AWS Step Functions 构建一个循环来顺序检索数据。看看这个博客 post:https://read.acloud.guru/processing-an-arbitrary-number-of-jobs-with-aws-step-functions-c185c2d2608
你的另外两个问题(分配键和随后的充实和更新)需要更多的上下文和世界,如果 post 作为单独的问题进行编辑可能是最好的。
一些评论。
We need to pull in a very large data set (hundreds of thousands of records) from a third-party API, which delivers paginated records in max groups of 50;
这意味着大约 "thousands" 次调用第三方 API。在你提到的问题的其他地方 "several hours"。使用 API 的提供者可以加载此负载吗?只有一件事要考虑,你的情况是你没有。
Making the API calls in a recursive lambda function (due to pagination);
非常小心 递归 Lambda 函数调用,即异步调用自身的 Lambda 函数。可能会发生这样的情况,由于一个错误,Lambda 永远不会停止调用自己,然后您会陷入 Lambda 调用的无限循环并增加费用……它可以停止,但它是一个 PITA。
Storing the results of the call in an S3 bucket as a single - or multiple - json files;
如果您想使用 S3,我可能建议将聚合的数据存储到更少的文件中。您没有提到每条数据的大小,但是大量的小文件对于 S3 来说并不理想。另一方面,只有一个巨大的(例如,几十或几百 GB 或更多)对于以后 processing 来说并不理想(即使 S3 可以毫无问题地处理它) .
我建议您调查两件事:
- Step Functions。
由于您需要处理第 3 方的分页 API,您可以在 Step Functions 中定义一个状态机来为您调用 Lambda。 Lambda 会做它的事情(下载一堆记录,将它们存储在 某个地方 )并且 return 或者下载记录的数量,或者待处理记录的数量,类似的东西.然后 Step Functions 的状态机将负责决定是否再次调用下载 Lambda 的逻辑(甚至可能使用基于先前调用的值 return 的参数)或者是否完成。
这样,您就可以很好地分离关注点:一个超级特定的 Lambda 函数,它只摄取东西;并且您将分页逻辑分开(甚至可能 "parallelism" 或 "timing" 逻辑,如果出于某种原因您被要求 "slow down" 您对第 3 方的调用 API) .
- Kinesis Firehose
Kinesis Firehose 是一种流式数据管道。基本上,您配置一个 firehose 流来为您聚合记录并转储它们 "somewhere"(例如,S3 是一个有效目标)。您可以选择聚合方式(例如时间、数据量)。您甚至可以配置 Firehose 以调用 Lambda 函数在存储之前为您转换每条记录(例如,您可以在此处添加您的 2 个唯一标识符)。