如何设计在 Lambda 函数上运行的可扩展 ETL

Posted

技术标签:

【中文标题】如何设计在 Lambda 函数上运行的可扩展 ETL【英文标题】:How to design a scalable ETL running on Lambda functions 【发布时间】:2019-08-30 14:59:18 【问题描述】:

我正在构建一个 ETL,将数据从各种 Postgres 数据库导入 S3 到 Redshift。我希望我的 ETL 具有以下约束和目标: 1. 所涉及的每个数据库一次都有一个查询。 2. 最短完成时间。 3. 便于开发者向 ETL 添加新数据集。 4. 可扩展到更多数据库和更多数据集。

由于超时而失败的设计

我通过以下方式使用 Lambda 函数计划了这一切:

lambda_1:由 cron 触发。触发多个可以并行运行的 lambda_2。每个源数据库触发一个 lambda_2。还会触发一个 lambda_4。

lambda_2:将其数据库中的所有数据集顺序导入 S3。

lambda_3:由文件放入 S3 触发,将相应的数据集名称添加到 SQS 队列中。

lambda_4:由 lambda_1 触发。有数据集列表。一次从 SQS 队列中弹出一条消息,然后将该数据集从 S3 导入 Redshift。一旦它导入了列表中的所有数据集,就会触发 lambda_5。

lambda_5+:(续)

如果我们要导入的源数据库中有许多数据集,我会遇到问题,因为相应的 lambda_2 可能会在完成导入之前超时。 出于类似的原因,我也会遇到 lambda_4 的问题,因为它将按顺序将每个数据集从 S3 导入 Redshift。

难以添加新数据集的设计

另一种方法是创建链式 lambda,每个数据集都有一个(例如,可能使用 Step Functions 链接它们)。我仍然可以使用 S3 文件触发器将该数据集放入 SQS 队列中,从而将导入 S3 与导入 Redshift 分离。

此解决方案有效,但很丑陋 (imo),并且难以添加新数据集,因为必须为其创建几个新的 lambda。

另一个更好的设计?

所有这一切的替代方案是放弃使用 Lambda 并使用……AWS Fargate?还有什么?期待设计建议。

【问题讨论】:

您应该使用 AWS EMR 运行 Spark 集群。 【参考方案1】:

lambda_2 在完成导入之前可能会超时

是的,Lambda 的 15 分钟超时在执行可能需要一些时间的 ETL 时令人头疼。

如果您不介意使用 Python,我建议您使用 AWS Glue Python Shell 作业和可能的 AWS Glue 工作流。使用 Glue 工作流程,您可以让其他作业触发作业。您将获得良好的可见性和自动重试。

如果这对您不起作用,那么将 ECS 与 Fargate 结合使用并与步进函数进行协调。

【讨论】:

【参考方案2】:

基于您的用例的最佳解决方案是使用 Aws 胶水 python shell 作业,它们将充当您的扩展 lambda。

然后,您可以使用 Glue 工作流程或步进函数来编排这些作业。

这里的好处是它们是无服务器的,由 aws 管理,而 ecs 你必须设法开始,而且对于这项任务来说也是一种矫枉过正。

【讨论】:

以上是关于如何设计在 Lambda 函数上运行的可扩展 ETL的主要内容,如果未能解决你的问题,请参考以下文章

如何使用AWS Lambda函数在本地系统上执行文件

Lambda如何使用?

在 AWS lambda 上运行 graphql 应用程序

MATLAB Runtime 可以在 AWS Lambda 上执行吗?

在现有 S3 对象上运行 S3-put 触发的 Lambda 函数?

python 如何在Amazon Lambda函数中运行报纸