我有一个包含近 200k 个项目的 dynamodb 表。我需要为其中的每个项目触发一个 lambda(将每个项目作为输入发送到 lambda)。我想对表中的所有项目每 x 小时执行一次。表中的数据每 5 天左右更改一次。
有没有一种无服务器的方法可以通过 SQS 等自动将所有项目获取到 lambda?
我不能让 lambda 扫描整个表,因为 lambda 处理它太多(给定 300 秒的限制等)。
谢谢,维诺德。
我有一个包含近 200k 个项目的 dynamodb 表。我需要为其中的每个项目触发一个 lambda(将每个项目作为输入发送到 lambda)。我想对表中的所有项目每 x 小时执行一次。表中的数据每 5 天左右更改一次。
有没有一种无服务器的方法可以通过 SQS 等自动将所有项目获取到 lambda?
我不能让 lambda 扫描整个表,因为 lambda 处理它太多(给定 300 秒的限制等)。
谢谢,维诺德。
扫描和更改 Dynamodb 中的所有数据都不可行。
您可以将所有 dynamodb 键保存在像 redis 这样的缓存中,可以有一个单独的作业从 redis 获取键并放入 lambda 正在侦听的 sqs。redis 键可以使用 dynamodb 流保持最新。
我会探索 SQS。让 lambda 批量获取多达 25 条记录(最大值),执行它需要的操作并标记记录(例如更新它们的时间戳 - 使用该时间戳作为过滤器,以确保您的提取始终只获取需要的记录更新。您可以继续获取记录。最终 lambda 将超时,但由于它没有完成,您将没有。有机会通过删除任务将您的 SQS 作业标记为完成。SQS 作业有一个可见期,当它结束时会导致它们重新出现在队列中,从而导致 lambda 运行另一个批处理,直到最终 lambda 找不到更多记录,然后可以删除 SQS 作业。当我们的索引映射发生变化时,我们使用它来刷新所有记录的弹性搜索索引。
当您说要“触发”其中的每个项目时,并不是 100% 清楚您的意思。一般来说,我认为 DynamoDB 流式传输,但某些事情必须导致记录由流处理。这通常通过UpdateItem
对每条记录进行简单的设置来完成,将可能不属于您的数据的字段设置为当前时间或其他独特的内容。从那里,您将通过在流上触发的 lambda 来处理每条记录。
循环数据的 100% 无服务器方式如下:
Dynamo 没有提供为已经存在的项目触发 lambda 的好方法,有几种方法可以解决这个问题:
您提到您担心 lambda 没有足够的资源来扫描表中的所有项目,您可以尝试以较小的块对数据进行操作以避免遇到资源限制。Lambda 的最大执行时间为 15 分钟,这对于大多数工作来说应该足够了。(请注意,在 Lambda 中,CPU 与内存一起扩展,因此根据作业过度配置内存实际上可以通过减少函数完成所需的时间来为您节省资金。)
在使用 Fargate 的 ECS 中,您可以按 cron 计划无服务器地创建任务。如果您担心资源限制,您可以为每个任务配置多达 4 个 vCPU 和 32GB 内存,这将大大降低您达到资源限制的可能性。这是一些有关如何设置的文档。
您可以将 dynamo 表配置为在表中的数据被Inserted、Modified或Removed时触发 lambda ,然后您可以在项目进入或更改时对其进行处理。您甚至可以将其配置为批量更改最多 10 个项目减少 lambda 调用。这是文档的链接。
注意:此方法不会针对表中已有的项目触发。但是,您可以通过编写脚本来更新这些项目上的任意字段来解决此问题。