AWS上的Cron(或一般的分布式系统)

Rya*_*yan 7 php mysql cron lamp amazon-web-services

我很惊讶我无法在此找到更多,但唉,我仍然找不到答案.我们最近转换为AWS,将我们简单的网站转移到更强大和可靠的系统.当前令我困惑的是在分布式系统上管理cron作业,当cron作业被推送到环境中的每个实例时.

这是用例:

背景

建立

我们正在运行传统的LAMP堆栈.可能是第一个问题,但这是我们得到的.

数据库表

table1

 - id int(11)
 - start date
 - interval int(11) (number of seconds)

table2

 - id int(11)
 - table1_id int(11)
 - sent datetime
Run Code Online (Sandbox Code Playgroud)

目标

目标是脚本每天运行一次并检查以下内容:

  1. 目前的日期已过 table1.start
  2. table1.start <当前日期
  3. table1.interval > 0
  4. 今天是一个完整的间隔距离(如果间隔是7天[以秒为单位],则会失败,这是第6天)
  5. 有中没有条目table2,从而table2.sent在今天和table2.table1_id以前的检查相匹配.

如果所有这些检查都通过,我们会为具有间隔的每个table1在table2中插入一个条目.这也意味着我们根据表2中的数据发送电子邮件.

问题

基本上,我们有两个查询,由上述块表示.问题是在分布式系统上,每个实例将同时运行cron(或在彼此的毫秒内).没有"事务"的概念,因此如果table2在其他实例执行第一个查询之前没有机会插入,则每个实例都会发送一封电子邮件.

解决方案???

我对此做了大量的研究,但我提出的唯一可能的解决方案详述如下:

Cron实例

设置一个负责运行cron作业的独立实例.虽然这肯定(据我所知)工作,但是对于一项工作而言,这是非常昂贵的,这项工作不是非常昂贵,而且最多只需要每天运行一次.

PHP调度程序

设置cron以定期运行充当调度程序的PHP脚本.研究表明,这是我们有限时间和金钱最简单的路线.我遇到的问题是,这似乎将并发问题从使用作业转移到调度作业.您何时安排作业,以便从运行cron的每个实例不同时安排多个作业?

这种方法看起来也非常"kludgy"(借用我朋友最喜欢的词),我不得不同意.

交易

虽然我对此进行了相当多的研究,但并发性总是通过数据库中的原子事务来解决,但据我所知,使用LAMP并不容易实现.但也许我错了,我很乐意证明这一点.

最后

所以,如果有人能帮我解决这个问题,我将非常感激.也许我的谷歌搜索技能变得生疏,但我无法想象我是唯一一个遭受这个(可能是简单的)任务的人.

Mic*_*art 3

查看 Gearman 项目http://www.gearman.org。基本架构是,您将拥有一台机器作为作业服务器,所有其他机器都成为该服务器的客户端。

您可以在作业服务器上设置 crontab,以将要执行的命令发送到通过 Gearman 连接的所有客户端。然后,您可以使用 PHP 对 cron 作业进行切片和切块,并根据需要深入了解 Map/Reduce。

这是关于概念及其工作原理的很好的教程:http://www.lornajane.net/posts/2011/Using-Gearman-from-PHP

不要因为立即与 Gearman 这样的公司合作而感到沮丧。分布式 cron 系统可能很复杂,但一旦你掌握了它,你就会没事的。

FWIW,我们在 Amazon EC2 上的 Gearman 工作农场中每分钟处理数千个 cron 脚本。我们非常喜欢它。