需要关于cron jobing的一个非常大的过程的建议

时间:2010-03-25 00:10:16

标签: php cron

我有一个PHP脚本,它从外部服务中获取数据并将数据保存到我的数据库中。我需要这个脚本每分钟为系统中的每个用户运行一次(我期望成千上万)。我的问题是,每分钟运行每个用户最有效的方法是什么?起初我以为我会有一个函数从我的数据库中抓取所有用户ID,遍历id并为每个用户执行任务,但我认为随着用户数量的增长,这将需要更长时间,而不再间隔1分钟。也许我应该排队用户ID,并为每个人单独执行任务?在这种情况下,我实际上不确定如何继续。

提前感谢任何建议。

修改

回答Oddthinking的问题:

我想同时为每个用户启动流程。当每个用户的过程完成时,我想等待1分钟,然后再次开始该过程。所以我想每个用户的每个进程都应该是异步的 - 用户1的进程不应该关心用户2的进程。

回答sims的问题:

我无法控制外部服务,外部服务的用户与我的数据库中的用户不同。我担心我不知道任何其他脚本语言,所以我需要使用PHP来做到这一点。

5 个答案:

答案 0 :(得分:2)

我是否正确总结?

您希望每分钟执行数千项任务,但您不确定是否可以及时完成这些任务?

您需要决定何时开始按计划运行。

  • 你一直坚持到最后,然后立即重新开始?
  • 你继续走,直到你完成,然后等一分钟,然后重新开始?
  • 你是否中止了这个过程,无论它到哪里,然后重新开始?
  • 你是否放慢了频率(例如从现在开始,每2分钟一次)?
  • 您是否有两个进程同时运行,并希望下一次运行更快(如果您第一次清理积压,这可能会有效,因此第二次运行将很快运行。)

这些问题的答案取决于申请。根据答案,Cron可能不适合您。您可能最好让流程永久运行并自行安排。

答案 1 :(得分:1)

所以,让我直截了当地说:你每分钟都在为数据库中的每个用户查询一个外部服务(什么是SOAP?MYSQL?),并将结果存储在同一个数据库中。这是对的吗?

这似乎是一个设计问题。

如果外部服务上的用户与数据库中的用户相同,则两者应该更紧密地配置。我不知道PHP是否是同步这些数据的方法。如果你提供更多细节,我们可以考虑另一个解决方案。如果您控制外部服务,您可能希望让该服务转储它的数据,甚至直接写入数据库。其他一些同步机制可能更好。

修改

您似乎正在创建一个为用户存储数据的应用程序,然后可以按时间顺序查看。否则,您也可以在用户请求时获取数据。

  1. 在go中获取所有用户ID。

  2. 逐个迭代它们(假设所提取的数据对每个用户来说都是唯一的)并且(因为PHP线程不存在AFAIK,你必须在这里创造)为每个请求调用一个进程如果一个用户没有返回数据,你希望它们全部同时执行而不会延迟。

  3. 所述进程应在返回后立即将返回的数据插入到数据库中。

  4. 至于cron是否适合这项工作:只要你拥有一台足够强大的服务器,可以同时处理数以千计的上述cron作业,你应该没问题。

    您可以通过多个PHP脚本获得创意。我不确定,但如果每个CLI调用PHP都启动一个新的PHP进程,那么你可以这样做。

    foreach ($users as $user)
    {
        shell_exec("php fetchdata.php $user");
    }
    

    这一切都非常沉重,你不应该期望用PHP做得很好。做一些测试。不要相信我的话。

答案 2 :(得分:1)

数据库可以立即处理BULKS记录。如果您正在逐个处理它们,那么您正在寻找麻烦。您需要找到批量处理“每分钟”任务的方法,以便通过执行SINGLE(复杂)查询,检索所有受影响的用户信息;那么,你会对结果进行PHP处理;然后,在另一个查询中,您将结果推回到数据库中。

答案 3 :(得分:1)

根据你的大图描述,听起来你有一个死胡同的设计。如果你能够立即使用它,它很可能非常脆弱,根本不会扩展。

我猜测如果你无法控制外部服务,那么外部服务可能不会因为你的脚本受到这样的打击而感到高兴。你有没有按照总体计划与他们联系?

你真的需要每次都做所有用户吗?是否有任何时间戳可用于更具选择性地关注哪些用户需要“更新”?也许如果你能够更好地描述目标,我们可以提供更具体的建议。

答案 4 :(得分:1)

鉴于您想要同时运行用户处理......

跳出来的最简单的解决方案是每个用户拥有一个线程。在Windows上,线程比进程便宜得多。

但是,无论您使用线程还是进程,同时运行数千个几乎肯定是行不通的。

相反,拥有一个的线程。池的大小取决于您的机器一次可以轻松处理的线程数。我希望30-150这样的数字可以达到您想要的范围,但这在很大程度上取决于硬件的容量,而且我可能会超出另一个数量级。

每个线程都会抓取下一个用户,因为它是从共享队列中处理的,处理它,并将其放回队列的末尾,可能是一个不应该处理它的日期。

(根据处理的数量和类型,这可以在数据库的单独框中完成,以确保数据库不会因非数据库相关处理而过载。)

此解决方案可确保您始终尽可能多地处理用户,而不会使计算机过载。随着用户数量的增加,处理频率会降低,但总是和硬件允许的一样快。

相关问题