简体   繁体   English

设计重复的PHP / MySQL任务

[英]Designing Repeating PHP/MySQL Task

I have a design headache here, I'm using PHP and MySQL in conjunction with Java (my project is an Android application). 我这里的设计很头疼,我将PHP和MySQL与Java结合使用(我的项目是Android应用程序)。 I have to decide how to run a series of server side calculations at regular intervals. 我必须决定如何定期运行一系列服务器端计算。 There is a wealth of material here on SO addressing how to create cron jobs and so on, and that's great, I may very well end there, but I'm not sure about how to tackle this part of my project in a broader sense. SO上有很多关于如何创建cron职位的材料,等等,那很好,我很可能就此结束,但是我不确定如何从更广泛的意义上解决项目的这一部分。

The application is completely centred upon the geographic locations of users. 该应用程序完全以用户的地理位置为中心。 They're always organised in clusters of anywhere between 4 and 40, and these clusters form one instance record in my database. 它们总是组织在4到40之间的任何群集中,这些群集构成了我数据库中的一个实例记录。 These instances can become active or inactive at any time. 这些实例可以随时变为活动或不活动。

The Task 任务

For each record in my database, or, I prefer instance, at each epoch, I want to recompute the centroid of the instance from its user locations (that's easy enough, particularly using a scalar approach given their close proximity), effectively shifting the location of the instance itself by updating latitude and longitude values in the database for the instance. 对于数据库中的每个记录,或者我更喜欢实例,在每个时期,我想从其用户位置重新计算实例的质心(这很容易,特别是在考虑到它们的紧密距离的情况下使用标量方法),从而有效地移动了位置通过更新实例数据库中的纬度和经度值来确定实例本身。 Users will subsequently receive these new instance centroid coordinates at regular intervals when they call home. 用户随后将在回叫之时定期接收这些新实例质心坐标。

The Method 方法

This is where it gets messy due to my rank inexperience. 由于我的等级缺乏经验,这里很混乱。 I started out by writing a relatively simple calculation involving one SQL select query and one subsequent SQL update operation, for each instance, at each epoch. 我首先编写了一个相对简单的计算,在每个时期针对每个实例涉及一个SQL选择查询和一个后续的SQL更新操作。 If we assume an update interval of around 20-30 seconds for now, that's less than one minute, apparently this breaches a limitation of 1min for cron jobs. 如果我们现在假设更新间隔为20-30秒左右,则不到一分钟,显然,这超出了cron作业1分钟的限制。 (It should be noted that the time difference between epochs can be hardcoded, if absolutely necessary). (应注意,如果绝对必要,则可以将各个纪元之间的时间差进行硬编码)。

In the short term, this process might only take a negligible amount of time to execute, due to the fact there would be very few instances/clusters. 在短期内,由于几乎没有实例/集群,因此执行此过程可能只花费很少的时间。 However, it would potentially stack up to a lot of SQL queries and a lot of time to process all of the calculations at some point later if the number of instances ran into the thousands... In order to reduce unnecessary load, I naturally want to incorporate some mechanism to exclude inactive instances, though I guess it is still conceivable that the required calculation time could exceed the epoch interval. 但是,如果实例数达到数千,那么它将潜在地堆积大量SQL查询和大量时间在以后某个时刻处理所有计算...为了减少不必要的负载,我自然希望合并一些机制以排除不活动的实例,尽管我想仍然可以想象所需的计算时间可能会超过纪元间隔。 I guess that's an issue for (much) later. 我想这是(很多)以后的问题。

The Question 问题

As it stands now, the question is two-fold: 就目前而言,问题有两个:

  1. I want to execute the same simple function for all active instances at each epoch. 我想在每个时期为所有活动实例执行相同的简单功能。 So, is there any more efficient way to do this than to run that many iterations? 那么,有没有比运行这么多次迭代更有效的方法了? Can I somehow update many table rows at once, using one big, final SQL update query? 我可以使用一个大的最终SQL更新查询以某种方式一次更新许多表行吗? Is something like mysqli_multi_query() actually very helpful here? 像mysqli_multi_query()这样的东西实际上在这里很有帮助吗? (At this point I don't have mysqli). (目前我没有mysqli)。
  2. How can I best implement a timer or trigger mechanism to re-fire this process at each epoch, given the fact it may violate the 1min limit I've been reading about for cron jobs? 考虑到它可能违反了我为cron作业所阅读的1分钟限制,我如何最好地实现计时器或触发机制来在每个时期重新触发该过程?

My Idea 我的想法

My current approach is as follows: 我当前的方法如下:

  1. Run one SQL select query to set it all up for the current epoch, fetching instance ID numbers requiring a centroid shift. 运行一个SQL选择查询以将其全部设置为当前纪元,以获取需要重心移位的实例ID号。
  2. Populate a PHP array with those instance ID's 使用这些实例ID填充PHP数组
  3. Sequentially shift each instance using a loop and either one or very many SQL updates (see above) to write the new coordinate pairs to the database. 使用循环和一个或多个SQL更新(请参见上文)顺序移动每个实例,以将新的坐标对写入数据库。
  4. Schedule this task to be carried out at each epoch (in other words, every x seconds) 安排此任务在每个时期执行(换句话说,每x秒执行一次)

Is the above approach sound? 上面的方法听起来合理吗? At this point, I plan to do it this way unless there's a better suggestion. 在这一点上,除非有更好的建议,否则我打算以这种方式进行操作。 I really don't have a solid handle on how I'm going to schedule the task to execute at each epoch (Point #4), however... I've looked all over the place and I can't solve this myself without some guidance, I'm just not very good yet. 对于如何安排任务在每个时期(第4点)的执行方式,我确实没有足够的把握,但是...我到处都是,我自己也解决不了没有一些指导,我还不是很好。 :) As always, any suggestions would be greatly appreciated. :)与往常一样,任何建议将不胜感激。

You might consider moving from a scheduled task to an update as needed approach. 您可能会根据需要考虑从计划任务转移到更新。 This is fairly easy to accomplish, but there are tradeoffs. 这相当容易实现,但是需要权衡取舍。

  • Add a datetime field called Last Updated 添加名为上次更新的日期时间字段

  • Every time you query the object, check the last updated field for 每次查询对象时,请检查上次更新的字段是否存在
    "freshness" (in your case, if it was > than 30 seconds ago) “新鲜”(在您的情况下,如果> 30秒前)

  • If its fresh, send the data to the user. 如果新鲜,则将数据发送给用户。

  • If it isn't fresh, recalculate the data and save it to the database 如果不新鲜,请重新计算数据并将其保存到数据库
    (making sure to change the last updated field). (确保更改最后更新的字段)。 Then, send the new 然后,发送新
    data to the user. 数据发送给用户。

This will eliminate the need for a scheduled task & get rid of the waste of updating every row. 这将消除对计划任务的需要,并且消除了更新每一行的浪费。 However, it can slow down responses to the user. 但是,它可能会减慢对用户的响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM