【问题标题】:Tracking Async Lambda execution on AWS跟踪 AWS 上的异步 Lambda 执行
【发布时间】:2019-04-04 21:49:40
【问题描述】:

我正在尝试构建一个调用 AWS lambda 的流程,然后该流程利用 AWS SNS 发送触发更多 lambda 的消息。每个此类触发的 lambda 都会将输出文件写入 S3。流程如下图-

我的问题是——我怎么知道所有的 lambda 表达式都写完文件了?我想执行另一个收集所有这些文件并进行合并的进程。我可以想到两种明显的方法 -

  1. 持续监控 s3 中与 SNS 消息一样多的输出文件。一旦总数达到,调用最终的合并 lambda。
  2. 使用数据库作为同步源,为该特定作业/会话写入计数并持续监控它,直到计数达到 SNS 消息计数。

这两种解决方案都需要不断轮询,我想避免这种情况。我想以事件驱动的方式做到这一点。我希望 Amazon SQS 能够通过某种“空队列 lambda 触发器”来拯救我,但 SQS 仅支持 lambdas 触发新消息。在 AWS 中是否有任何已知的方法可以以事件驱动的方式实现这一目标?非常感谢您的建议/cmets/答案。

【问题讨论】:

  • AWS Step Functions.
  • 还有其他选择吗?
  • 如果您事先知道事物的数量,您可以在 DynamoDB 中初始化一个计数器,然后在工作完成时自动递减它。使用 DynamoDB Streams 在计数器发生突变时触发 Lambda 调用,并在计数器达到零时触发您的下一个阶段(或工作结束)。我没有亲自实施,但可能值得研究。
  • @jarmod DynamoDB Streams 上的触发器似乎在创建新记录时可用。当计数器达到零时,似乎没有办法触发事件。我认为最好的解决方案是 SQS 队列清除事件,但不幸的是,SQS 没有提供任何此类事件触发器!。
  • 每当应用程序创建、更新或删除表中的项目时,DynamoDB Streams 都会写入一条流记录。

标签: java amazon-web-services architecture aws-lambda amazon-sqs


【解决方案1】:

我会在这里提出几个选项:

阶梯函数:

这是状态机的托管服务。它非常适合协调工作流程。

原子计数:

如果您事先知道事物的数量,您可以在 DynamoDB 中初始化 Atomic Counter,然后在工作完成时自动递减它。使用 DynamoDB Streams 在计数器发生突变时触发 Lambda 调用,并在计数器达到零时触发您的下一个阶段(或工作结束)。请注意,每当应用程序创建、更新或删除表中的项目时,DynamoDB Streams 都会写入一条流记录,因此计数器的每个突变都会触发您的 Lambda。

请注意,DynamoDB Streams 保证以下内容:

  • 每个流记录在流中只出现一次。

  • 对于在 DynamoDB 表中修改的每个项目,流记录的显示顺序与对项目的实际修改相同。

【讨论】:

    【解决方案2】:

    AWS Step Functions(一种托管状态机服务)将是显而易见的选择。 AWS 提供了一些示例作为起点。我记得其中一个是循环状态,您可能可以将其应用于此用例。

    我的另一个想法......

    创建一个包含文件列表的“Orchestration Lambda”...

    1. Orchestration Lambda 在循环中调用“文件编写器 Lambda”,传递文件信息。 invokeAsync(InvokeRequest request) 返回一个 Future 对象。 Orchestration Lambda 可以检查未来对象状态是否完成。

    2. Orchestration Lambda 可以对“File Writer Lambda”进行类似的调用,但使用更灵活的方法:invokeAsync(InvokeRequest request, AsyncHandler asyncHandler)。您可以创建一个实现此 AsyncHandler 的内部类,并在 Orchestration Lambda 中监控那里的完成情况。它比所有循环都干净一点。

    可能有很多方法可以解决这个问题,但有两种想法。

    【讨论】:

    • Orchestration Lambda 的问题有两个 - a) 从 lambda 开始 lambda 不是 Amazon 通常推荐的过程。我过去尝试过这个并遇到了一些限制。使用 s3,sqs,sns 作为触发 lambda 的服务是通常推荐的方式。 2)其次,在我的情况下,Orchestration Lambda 可能会超时(5 分钟)。
    • 嗯,这是一个笼统的说法。在许多情况下,lambda 到 lambda 通信可能是合适的。您的用例将根据任意数量的技术要求确定您提到的超时是其中之一。我们有一个 lambda 调度模式,每分钟有数万次调用,没有问题。如果您有一个长期运行的过程,听起来像阶跃函数是您查看的好地方。
    • 您根本看不到每分钟数千次调用的任何限制吗?你能简单地告诉我你的用例是什么吗?
    • 简而言之,它是 Web 应用程序的主要引擎。 API Gateway 有一些向 Lambda 发送请求的贪婪端点。 Lambda 分派到代码库中的类以执行业务逻辑或对 AWS 服务的外部调用或两者兼而有之。速度非常重要,每个请求都保持在 4500 毫秒以下,大多数平均要低得多。使用默认的 3,000 并发限制,我们在负载下没有问题。
    【解决方案3】:

    就个人而言,我更喜欢“Step Functions”这个想法。

    但如果你想简化你的架构,你可以创建触发 lambda 函数。在 lambda 函数设计器的左侧选择“S3 触发器”并将其配置在底部。

    了解更多 - Using AWS Lambda with Amazon S3

    但在这种情况下,您必须创建更复杂的 lambda 函数,它将检查所有适当的文件是否已上传到 S3,然后开始合并。

    【讨论】:

    • 感谢您的回答。即使使用步进函数,我也必须有一个触发 n lambda 并等待它们完成的步骤。这个等待的 lambda 是我试图避免的。使用 dynamodb 作为倒计时机制在我的场景中效果很好。
    【解决方案4】:

    上述问题似乎是 Saga 模式的合适候选者。 基本上Saga 被描述为任何长时间运行的分布式进程。

    如前所述,AWS 平台允许使用 Step 函数来实现 Saga,as described here enter

    【讨论】:

    • 谢谢。我避免使用步进函数,因为我不喜欢从另一个 lambda 启动同步/异步 lambda。就我而言,原子计数工作得很好。
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 2016-05-01
    • 2019-01-28
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多