1

我有这个设置

ApiGateway -> Lambda1 -> DynamoDB -> Lambda2 -> SNS -> SQS

这是我想要做的事情:

  1. 向 ApiGateway 发出 http 请求。
  2. ApiGateway 集成到 Lambda1,因此 Lambda1 被执行。
  3. Lambda1 将一个对象插入到 DynamoDB。
  4. DynamoDBStream 触发 Lambda2。批量大小为 100。
  5. Lambda2 为每条插入的记录发布一条消息到 SNS。
  6. SQS 订阅了 SNS。

基本上,如果我向 Api Gateway 发出 http 请求,我希望看到一条消息以 SQS 结尾。实际上,对于单个请求,一切都按预期工作。

我做了这个测试:

  1. 发出 10 个 http 请求来预热 lambda 函数并等待 30 秒。
  2. 创建 100 个线程。每个线程将发出一个 http 请求,直到总请求数为 10000。

测试的第二步在 110 秒内完成。我的 DynamoDB 配置为每秒 100 次写入,这 110 秒非常合理。110 秒后,我在 DynamoDB 表中看到这 10000 条记录

问题是消息在 SQS 中结束需要太多时间。我检查了 Lambda2 的日志,发现它在测试完成后 30 分钟仍然被触发。同样在 Lambda2 的日志中,我看到了这种模式。

Start Request
Message published to SNS...
Message published to SNS...
[98 more "Message published to SNS..."]
End Request

日志由这些行的重复组成。100 行“已发布消息”是有意义的,因为 DynamoDBStream 的批处理大小配置为 100。对 Lambda2 的每个请求需要 50-60 秒,这意味着所有消息需要大约 90 分钟才能最终到达 SQS。

困扰我的是,每个“开始请求”都在“结束请求”之后。因此,根本原因似乎是 DynamoDBStream 没有并行触发 Lambda2。

问题

为什么 DynamoDBStream 不并行触发 lambda 函数?我缺少配置吗?

解决方案

在从答案和评论中得到建议后,这是我的解决方案。

  1. 在发布每条消息之前,我正在重新创建 SNS 客户端。我在课堂上将其设为静态变量,Lambda2 在大约 15 秒内开始执行。
  2. 然后,我将 DynamoDB 触发器的批量大小增加到 1000。
  3. 在 Lambda2 中,我使用 10 个并行线程处理(发布到 SNS)DynamoDB 记录。
  4. 将 Lambda2 内存分配从 192MB 增加到 512MB。

通过这些优化,我可以在 SQS 中看到所有 10000 条消息,在发送所有 http 请求后 10-15 秒。

结论 :)

为了找到最佳(便宜且可接受的延迟)解决方案,我们需要使用不同的批量大小、线程数、分配的内存等进行几次测试。

4

1 回答 1

2

目前还没有办法触发 DynamoDBStream 并行触发。它只是顺序交付和批量配置。

也没有部分交货。如果您有批量交付给您的 lambda,则需要批量完成所有元素。否则它将在以后交付相同批次或更多记录。

此外,您需要为下一批成功完成 lambda,如果出错,它将重复调用 lambda,直到它成功交付或流中数据的生命周期。

于 2017-09-24T17:52:21.940 回答