使用AWS服务进行长时间任务调度

5
我的应用程序严重依赖于AWS服务,我正在寻找一种基于它们的最佳解决方案。Web应用程序触发一个定时任务(假设无限重复),需要执行一定数量的资源。单次任务运行通常最多需要1分钟。
目前的想法是通过SQS传递作业,并根据队列大小在EC2实例上生成工作程序。(这部分或多或少清楚)但我很难找到一个合适的解决方案来实际触发某些间隔的作业。假设我们正在处理10000个作业。因此,对于调度程序运行10k cronjobs(作业本身非常简单,只需通过SQS传递作业描述)同时运行似乎是一个疯狂的想法。因此,实际问题是如何自动缩放调度程序本身(考虑到调度程序重新启动,创建新实例等情况)?或者调度程序本身作为应用程序是多余的,更明智的做法是依靠AWS Lambda函数(或提供调度的其他服务)?使用Lambda函数的问题是某些限制以及单个函数提供的128mb内存实际上太多了(20mb似乎足够了)
或者,工作程序本身可以等待一定时间并通知调度程序再次触发作业。假设频率为1小时:
1. Scheduler sends job to worker 1
2. Worker 1 performs the job and after one hour sends it back to Scheduler
3. Scheduler sends the job again

然而这里的问题是工人可能被刻度缩放。

重点 我正在尝试实现一个轻量级的调度程序,它不需要自动扩展,并且作为传输作业描述的中心,绝对不应在服务重新启动时出现限制。


1
"长时间运行的任务" .. "最多需要1分钟" :/ - Andy Hayden
1个回答

5
Lambda非常适合这种情况。您有很多短时间运行的进程(~1分钟),而Lambda适用于短进程(目前为止最多5分钟)。非常重要的是要知道CPU速度与RAM成线性关系。如果我没记错,一个1GB的Lambda函数相当于一个t2.micro实例,而1.5GB RAM意味着1.5倍的CPU速度。这些函数的成本如此之低,以至于您可以直接执行此操作。128MB RAM具有微型实例的1/8 CPU速度,因此我实际上不建议使用它们。
作为队列机制,您可以使用S3(是的,您没有看错)。创建一个存储桶,并在创建对象时让Lambda worker触发。当您想要安排作业时,请将文件放入存储桶中。Lambda会立即启动并处理它。
现在您必须遵守一些限制。这样,您最多只能同时拥有100个工作程序(活动Lambda实例的总数),但您可以要求AWS增加此数量。
成本如下:
- 每1000次PUT请求,费用为0.005美元,因此每一百万个作业请求费用为5美元(这比SQS更贵)。 - Lambda运行时。假设正常的t2.micro CPU速度(1GB RAM),这将花费0.0001美元/作业(60秒,前300,000秒免费= 5000个作业)。 - Lambda请求。每一百万个触发器的费用为0.20美元(前一百万个免费)。
这种设置不需要您自己的任何服务器。这不会崩溃(除非AWS本身出现问题)。
(完成后不要忘记从S3中删除作业)

感谢您的建议。还有一个问题,如果我们不是要生成许多Lambda函数,而是制作一些(假设我们创建每5分钟、每小时、每天等运行的单独函数)。每个Lambda函数都将从S3中检索作业,并通过SQS传递它们。这种架构中是否会有任何可能引起问题的因素? - Yerken
你需要考虑S3键(文件名)的结构,以便Lambda函数不会重复包含文件(Lambda函数并不知道其他函数是否已经处理过该文件)。好在你可以通过S3事件触发Lambda函数,这样就永远不会出现这个问题。然后你可以将它发送到SQS(每个Lambda函数都有一个SQS调用,这不是问题,并且只需要<1秒)。但是如果你可以批量处理,为什么不在1个SQS操作中定义批处理,而完全不使用S3和Lambda呢? - Luc Hendriks
你能详细说明一下在一个SQS票证中定义批处理的意思吗?谢谢。 - Yerken
不是每个SQS票据一个作业,而是在一个SQS票据(或1批次)中定义一组作业。然后当您处理该票据时,实例可以一次处理整个批次。在这种情况下,SQS票据的数量为N/B,其中N是所需作业的数量,B是批量大小。因此,如果您将50个作业放入一个票据中,则只需要200个SQS票据即可处理10,000个作业。 - Luc Hendriks
是的,这就是计划。我将运行Lambda函数来安排那些SQS票据。因此,如果有10k个作业需要每5分钟运行一次,我将通过SQS从Lambda函数(定时函数)传递200个票据到处理实例。但是作业本身将存储在S3中(但可以使用DynamoDB作为替代方案),并且在每个周期迭代中从Lambda函数中获取。 - Yerken
我想建议使用SNS作为Lambda的备选事件源,也许更适合,因为每个作业可以单独传递。 - user1893702

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接