我正在尝试想出一种方法,通过每 N 小时调用一次 aws lambda 来在特定时间间隔处理数据片段。
例如,每 6 小时解析一次特定 url 的页面,并将结果存储在 s3 存储桶中。
以这种方式处理许多(~100k( URL。
当然,您可以拥有一个托管一些会触发 lambda 的计划程序的 VM,如本答案中所述,但这会破坏"无服务器"方法。
那么,有没有办法仅使用 aws 服务来做到这一点?
我尝试过不起作用的事情:
SQS- 可以延迟消息,但最多只能延迟 15 分钟(我需要几个小时(,并且SQS和 Lambda 之间没有内置集成,因此您需要一些轮询代理(lambda?(来一直轮询 qeueu 并向工作线程 lambda 发送新消息,这再次打破了仅在计划时间执行的要点;
- CloudWatch Alarmarms可以向 SNS 发送触发 Lambda 的消息。您可以使用未来的指标时间戳实现定期 lambda 调用,但是警报消息不能连接自定义数据(想想上面示例中的 URL(,因此这也不起作用;
- 我可以通过编程方式创建 LambdaCloudWatch 计划触发器,但它们也无法将任何数据传递给 Lambda。
我能想到的唯一方法是拥有一个带有"url"记录的 dynamo DB 表,每个记录都有上次"处理"的时间戳,并且具有周期性的 lambda,它将查询该表并将"旧"记录作为作业发送到另一个"worker"lambda(直接或通过 SNS(。 这将有效,但是您仍然需要一个"轮询"lambda,随着要处理的项目数量的增加,这可能会成为瓶颈。
还有其他想法吗?
每 6 小时 100k 个作业,听起来不像是无服务器 IMO 的一个很好的用例。就个人而言,我会使用相关的 cron 表达式设置一个 CloudWatch 事件,该表达式触发 Lambda 启动处理所有 URL(存储在 DynamoDB 中(的 EC2 实例,并在处理最后一个 URL 后将 EC2 实例编写脚本以关闭。
但这不是你问的。
您可以使用相关的 cron 表达式设置一个 CloudWatch 事件,该表达式生成一个 lambda(业务流程协调程序(,从 DynamoDB 甚至 S3 文件读取网址,然后为每个网址调用第二个 lambda(工作线程(以实际解析页面。
使用此模式,您将开始在 1000 个 lambda(1 个业务流程协调程序和 999 个工作线程(时遇到并发问题,如果在同一区域中运行其他 lambda,则更少。您可以要求 AWS 提高此限制,但我不知道他们会在什么情况下这样做,或者他们会在多高的情况下增加限制。
从这里你有三个选择。
将有效负载拆分为每个工作线程 lambda,以便每个实例接收多个要处理的 URL。
在网址列表中添加另一列,并使用此列对网址进行分组(例如,前 500 个标有 1,第二个 500 个标有 2,依此类推(。然后,业务流程协调程序 lambda 可以批量从列表中删除 url。这将要求您以更高的频率运行 CloudWatch 事件并管理状态,以便业务流程协调程序 lambda 在调用时知道哪个是下一批(我只是在 S2 文件中存储变量以较小的规模执行此操作(。
将使用选项1和2的某种组合。
看起来,它适合将 AWS lambda 函数作为作业的批处理场景。它是无服务器的,但显然增加了对另一个 AWS 服务的依赖。
同时,它具有仪表板,处理状态,重试次数以及作业计划服务的所有特权。