【问题标题】:Designing Repeating PHP/MySQL Task设计重复 PHP/MySQL 任务
【发布时间】:2012-07-17 13:59:28
【问题描述】:

我在这里遇到了设计难题,我将 PHP 和 MySQL 与 Java 结合使用(我的项目是一个 Android 应用程序)。我必须决定如何定期运行一系列服务器端计算。这里有大量关于 SO 解决如何创建 cron 作业等的材料,这很好,我很可能会到此结束,但我不确定如何从更广泛的意义上解决我的项目的这一部分。

应用程序完全以用户的地理位置为中心。它们总是组织成 4 到 40 个之间的集群,这些集群在我的数据库中形成一个实例记录。这些实例可以随时变为活动或不活动。

任务

对于我数据库中的每条记录,或者,我更喜欢实例,在每个时期,我想从其用户位置重新计算实例的质心(这很容易,尤其是使用标量方法,因为它们非常接近),有效通过更新实例数据库中的纬度和经度值来移动实例本身的位置。用户随后会在打电话回家时定期收到这些新的实例质心坐标。

方法

由于我的等级缺乏经验,这就是它变得混乱的地方。我首先编写了一个相对简单的计算,其中涉及一个 SQL 选择查询和一个后续 SQL 更新操作,对于每个实例,在每个时期。如果我们现在假设更新间隔约为 20-30 秒,那不到一分钟,显然这违反了 cron 作业的 1 分钟限制。 (应该注意,如果绝对必要,可以硬编码时期之间的时间差)。

在短期内,这个过程可能只需要很少的时间来执行,因为实例/集群很少。但是,如果实例数量达到数千个,它可能会堆积大量 SQL 查询和大量时间来处理所有计算......为了减少不必要的负载,我自然想要结合一些机制来排除不活动的实例,尽管我想仍然可以想象所需的计算时间可能会超过 epoch 间隔。我想这是(很多)以后的问题。

问题

就目前而言,问题有两个方面:

  1. 我想对所有活动实例执行相同的简单函数 在每个时代。那么,有没有比这更有效的方法呢? 运行那么多迭代?我可以以某种方式更新许多表行吗 一次,使用一个大的、最终的 SQL 更新查询?是这样的 mysqli_multi_query() 在这里真的很有帮助吗? (此时我没有mysqli)。
  2. 如何最好地实现计时器或触发机制以重新触发 考虑到它可能违反 1min 的事实,每个时期的这个过程 我一直在阅读有关 cron 作业的限制?

我的想法

我目前的做法如下:

  1. 运行一个 SQL 选择查询以将其全部设置为当前纪元, 获取需要质心移位的实例 ID 号。
  2. 使用这些实例 ID 填充 PHP 数组
  3. 使用循环顺序移动每个实例,并使用一个或非常 许多 SQL 更新(见上文)以将新的坐标对写入数据库。
  4. 安排此任务在每个时期执行(换句话说, 每 x 秒)

上述方法合理吗?在这一点上,除非有更好的建议,否则我打算这样做。我真的不知道如何安排在每个时期执行的任务(第 4 点),但是……我已经到处找了,我自己也无法解决没有一些指导,我还不是很好。 :) 一如既往,任何建议将不胜感激。

【问题讨论】:

  • 如果你想让服务器计算/查询比一分钟一次更频繁,php 可能不是正确的工具。您应该使用一种技术(仅用于此目的)启用长时间运行的服务器任务。如您所知,这可能是一个不错的选择。
  • 在您的数据库中使用一个标记来表示脚本正在运行。在脚本开始时检查它是否正在运行,如果没有设置它并运行脚本。如果已设置,只需结束脚本。为了避免 1 分钟的间隔,应该使用一个命令调用脚本,例如进程记录();那么你可以处理 if(ok) sleep 过程,持续时间为 1 分钟并且不应该重叠
  • 如果我将更新间隔减少到 1 分钟,这确实会变得简单得多。我想我应该决定是否可以逃脱惩罚。我很感激帮助。干杯。

标签: php mysql recurring delayed-execution


【解决方案1】:

您可能会考虑从计划任务转移到按需更新的方法。这很容易实现,但需要权衡取舍。

  • 添加一个名为 Last Updated 的日期时间字段

  • 每次查询对象时,请检查上次更新的字段
    “新鲜度”(在您的情况下,如果是 > 30 秒前)

  • 如果是新鲜的,将数据发送给用户。

  • 如果不是新鲜的,请重新计算数据并将其保存到数据库中
    (确保更改最后更新的字段)。然后,发送新的
    数据给用户。

这将消除对计划任务的需要并摆脱更新每一行的浪费。但是,它可能会减慢对用户的响应速度。

【讨论】:

  • 如果用户正在请求信息,那么他们已经执行了一个脚本。只需将脚本的小版本标记为他们的语言环境即可。
  • 感谢您的建议,我会考虑一下。 :) 我希望保持实例转移过程独立于请求更新的用户。他们以不同的时间间隔请求包含其他数据的包,而实例的质心只是他们发送的数据的一小部分。
  • 考虑将所有逻辑封装在一个 getCentroid() 函数中。这将保持此特定操作的逻辑离散,但仍保持仅根据需要进行更新的节省。
猜你喜欢
  • 2013-01-02
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多