如何将Linux cron作业转换为"亚马逊方式"?

Tom*_*Tom 111 cron lamp scheduled-tasks amazon-ec2 amazon-swf

无论好坏,我们已将整个LAMP Web应用程序从专用计算机迁移到云计算(Amazon EC2计算机).到目前为止它很好,但我们做crons的方式是次优的.我有一个特定于亚马逊的问题,关于如何使用"亚马逊方式"在云中最好地管理cron作业.

问题:我们有多个Web服务器,需要为批量作业运行crons,例如创建RSS提要,触发电子邮件,实际上有很多不同的事情.但是cron作业只需要在一台机器上运行,因为它们经常写入数据库,因此如果在多台机器上运行,则会复制结果.

到目前为止,我们将其中一个网络服务器指定为"主网络服务器",并且它有一些其他网络服务器没有的"特殊"任务.云计算的权衡是可靠性 - 我们不需要"主 - 网络服务器",因为它是单点故障.我们希望它们都是相同的,能够升级和缩小,而不记得不将master-webserver从集群中取出.

我们如何重新设计我们的应用程序以将Linux cron作业转换为没有单点故障的临时工作项?

我的想法到目前为止:

  • 有一台专用于运行crons的机器.这将是一个更易于管理,但仍然是单点故障,并会浪费一些额外的实例.
  • 有些工作可以想象地从Linux crons转移到MySQL Events但是我不是这个想法的忠实粉丝,因为我不想将应用程序逻辑放入数据库层.
  • 也许我们可以在所有机器上运行所有crons,但是更改我们的cron脚本,所以它们都从一些实现锁定机制的逻辑开始,因此只有一个服务器实际上采取行动而其他服务器只是跳过.我不是这个想法的粉丝,因为它听起来可能有错误,我宁愿使用亚马逊最佳实践,而不是自己动手.
  • 我正在想象一种工作安排在某个地方的情况,添加到队列中,然后网络服务器可能都是一个工人,可以说"嘿,我会拿这个".亚马逊简单工作流服务听起来就是这种事情,但我目前对此并不了解,所以任何具体细节都会有所帮助.对于像cron一样简单的东西,它似乎有点重量级?它是正确的服务还是有更合适的亚马逊服务?

更新:自从问及我在YouTube上观看亚马逊简单工作流服务网络研讨会并在34:40(http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s)注意到的问题后,我看到了一个问题.幻灯片提到cron作为示例应用程序.在他们的文档页面" 亚马逊SWF的AWS Flow Framework样本 "中,亚马逊称他们有crons的示例代码:

... > Cron作业在此示例中,长时间运行的工作流会定期执行活动.可以证明能够继续执行新执行,以便执行可以运行很长一段时间....

我下载了适用于Java的AWS开发工具包(http://aws.amazon.com/sdkforjava/),并确保在一个荒谬的文件夹层中埋藏了一些java代码(aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

问题是,如果我是诚实的,这并没有真正的帮助,因为它不是我能用我的技能组合轻易消化的东西.PHP SDK中缺少相同的示例,并且似乎没有可以通过该过程的教程.所以基本上,我还在寻找建议或提示.

Tom*_*Tom 37

我注册了亚马逊金牌支持,问他们这个问题,这是他们的回答:

汤姆

我对我的一些同事进行了快速调查,然后在cron上空了,但是在睡觉之后我意识到重要的一步可能仅限于锁定.所以我寻找"分布式cron作业锁定",并找到了一个Apache项目Zookeeper的引用.

http://zookeeper.apache.org/doc/r3.2.2/recipes.html

http://highscalability.com/blog/2010/3/22/7-secrets-to-successfully-scaling-with-scalr-on-amazon-by-se.html

我也看到过使用memcached或类似的缓存机制作为使用TTL创建锁的方法.通过这种方式,您可以设置一个标志,TTL为300秒,其他任何cron worker都不会执行该作业.TTL过期后,锁定将自动释放.这在概念上与我们昨天讨论的SQS选项非常相似.

另见; Google的胖乎乎的 http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

让我知道如果这有帮助,并且随意提问,我们非常清楚我们的服务对于初学者和经验丰富的开发人员来说都是复杂而艰巨的.我们总是乐于提供建筑和最佳实践建议.

最好的祝福,

Ronan G.亚马逊网络服务


Nat*_*ens 13

我认为这个视频回答了你的确切问题 - cronjobs aws方式(可扩展和容错):

使用Amazon Simple Workflow在云中使用Cron

该视频使用实现cronjobs的特定用例描述了SWF服务.

如果您直接从crontab出发,解决方案的相对复杂性可能难以接受.最后有一个案例研究帮助我理解了额外的复杂性给你带来了什么.我建议观看案例研究并考虑您对可伸缩性和容错性的要求,以决定是否应该从现有的crontab解决方案进行迁移.

  • 这是一个很好的答案,因为它使用AWS提供的良好支持的工具,而SWF是一个功能强大的产品.唯一的缺点是imo,**SWF有一个重要的学习曲线**并且很难做复杂的事情.至少那是我在Java教程中的经验 (2认同)

Mac*_*ski 11

小心使用SQS进行cronjobs,因为它们不能保证只有"一台机器只能看到一个工作".他们保证"至少有一个"会收到消息.

来自:http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

问:我会收到多少次邮件?

Amazon SQS旨在为其队列中的所有消息提供"至少一次"传递.虽然大多数情况下每条消息只会传递给您的应用程序一次,但您应该设计系统,以便多次处理消息不会产生任何错误或不一致.

到目前为止,我可以考虑一个安装了Gearman Job Server实例的实例的解决方案:http://gearman.org/.在同一台机器上,您可以配置生成命令的cron作业,以在后台执行您的cronjob任务.然后,您的一个Web服务器(工作人员)将开始执行此任务,它保证只有一个人将接受它.无论你有多少工人(特别是当你使用自动缩放时).

这个解决方案的问题是:

  • Gearman服务器是单点故障,除非您使用分布式存储配置它,例如使用memcached或某些数据库
  • 然后使用多个Gearman服务器,你必须选择一个通过cronjob创建任务的服务器,所以我们再次回到同样的问题.但是,如果你能够使用Gearman这种单点故障看起来是非常好的解决方案.特别是你不需要大实例(在我们的情况下微实例就足够了).

  • @FrederikWordenskjold这是不正确的,即使已经将消息发送给一个客户端,它仍然可以被给予另一个客户端,因为SQS状态的复制是异步的.您甚至可以在"删除"之后给出一条消息的副本! (2认同)

use*_*905 10

亚马逊刚刚发布了Elastic Beanstalk的新功能.来自文档:

AWS Elastic Beanstalk支持
在运行预定义配置的环境中的工作线程环境层的定期任务,其中包含容器名称中包含"v1.2.0"的解决方案堆栈."

您现在可以创建一个包含cron.yaml配置计划任务的文件的环境:

version: 1
cron:
- name: "backup-job"          # required - unique across all entries in this file
  url: "/backup"              # required - does not need to be unique
  schedule: "0 */12 * * *"    # required - does not need to be unique
- name: "audit"
  url: "/audit"
   schedule: "0 23 * * *"
Run Code Online (Sandbox Code Playgroud)

我想象通过消息队列(SQS)可以在自动调整的环境中运行一次保险.当cron守护程序触发事件时,它将该调用放入SQS队列,并且队列中的消息仅评估一次.文档说如果SQS要处理许多消息,执行可能会延迟.


Jaa*_*ans 6

我现在第三次遇到这个问题,并且认为我已经填补了这个问题.我们已经暂时陷入了这种困境.我还是真的觉得AWS这里缺少的功能.

在我们的案例中,在查看可能的解决方案后,我们认为我们有两个选择:

  • 设置一个cronjob服务器,该服务器运行应该一次只运行一次的作业,自动调整它并确保在某些CloudWatch统计数据不是它们应该的时候替换它.我们使用cloud-init脚本来运行cronjobs.当然,这会导致停机,导致错过cronjobs(每分钟运行某些任务,就像我们一样).
  • 使用使用的逻辑rcron.当然,魔术rcron本身并不是真正的,它是用于检测失败节点(我们keepalived在这里使用)和"升级"另一个节点来掌握的逻辑.

我们决定采用第二种选择,因为它的速度非常快,而且我们已经拥有运行这些cronjobs的web服务器的经验(在我们之前的AWS时代).

当然,这个解决方案专门用于取代传统的单节点cronjob方法,其中时间是决定因素(例如"我希望工作A每天早上5点运行一次",或者像我们的情况一样"我想要工作B每分钟运行一次").如果你使用cronjobs来触发批处理逻辑,你应该真的看看SQS.没有主动 - 被动困境,这意味着您可以使用单个服务器或整个劳动力来处理您的队列.我还建议考虑SWF扩展你的员工队伍(尽管auto scaling在大多数情况下也可以做到这一点).

取决于另一个第三方是我们想要避免的.


Tom*_*Tom 6

亚马逊于12月12日发表了关于使用AWS Lambda调度SSH作业的博文.我认为这回答了这个问题.