我很惊讶,我无法在这方面找到更多,但唉,我仍然无法找到答案。我们最近转换为AWS,将我们的简单网站转移到更强大和更可靠的系统。目前让我莫名其妙的是在分布式系统上管理cron作业,当cron作业被推送到环境中的每个实例时。AWS上的Cron(或一般的分布式系统)
这里的用例:
背景
设置
我们正在运行一个传统的LAMP堆栈。可能是第一个问题,但这是我们得到的。
DB表
table1
- id int(11)
- start date
- interval int(11) (number of seconds)
table2
- id int(11)
- table1_id int(11)
- sent datetime
目标
的目标是,脚本会每天运行一次,并检查以下内容:
- 当前日期是过去
table1.start
table1.start
<当前日期 今天3210
table1.interval
> 0- 正是整体区间远
- 存在
table2
这样table2.sent
没有进入今天(这样会失败,如果时间间隔为7天[以秒],这是第6天)和table2.table1_id
匹配先前的检查。
如果所有这些检查都通过了,我们会为每个有间隔的表1插入一个条目到table2中。这也意味着我们根据表2中的数据发送电子邮件。
的问题
本质上,我们有两个查询,由上述块表示。问题是,在分布式系统上,每个实例将同时运行cron(或者相隔几毫秒)。没有“事务”的概念,因此如果在其他人运行第一个查询之前没有机会插入table2
,每个实例都会发送一封电子邮件。
解决方案???
我做的这个研究有相当数量,但我已经拿出了唯一可能的解决办法详述如下:
cron的实例
设立负责运行一个单一的,独立的实例cron工作。虽然这肯定会(据我所知)起作用,但这对于一份工作来说非常昂贵,而且这项工作不是非常昂贵,而且最多只需要每天运行一次。
PHP调度
设置cron来定期运行充当调度的PHP脚本。这是我们在研究表明它对于我们有限的时间和金钱来说最简单的时候所走的路线。我碰到的问题是,这似乎将并发问题从消费性工作转移到了调度工作。您什么时候安排这些工作,使得多个工作不是从运行cron的每个实例同时安排的?
这种方法也似乎很“kludgy”(借用我朋友最喜欢的词),我不得不同意。
交易
虽然我已经研究这个颇有几分,并发总是与数据库原子事务解决,但就我所知,这是不容易实现与LAMP。但也许我错了,我很乐意证明如此。
最后
所以,如果有人能帮助我这一个,我将不胜感激。也许我的谷歌搜索技能正在生锈,但我无法想象自己是唯一一个遭受这种(可能很简单)任务的人。
我没有足够的经验来把它变成一个非常有建设性的答案,但你有没有看过亚马逊的SWF?由于您已经在AWS上,可能是cron的可靠替代品。 – 2012-07-16 23:05:57
这可能听起来过于夸张,但也许你可以看看[Zookeeper](http://zookeeper.apache.org/)。它使用起来很简单,轻便,强大,并且可以让您的任务尽可能简单地协调/同步分布式任务。 – Viccari 2012-07-16 23:25:37
也许值得注意的是,我们正在使用Kohana。我想知道是否有某种程度的锁定我可以在数据库查询上进行确认,以确保交易是原子级的和串联的。 – Ryan 2012-07-17 01:19:37