PHP、MySQL、Cron高效维护大型表中当前/实时数据的方法?
这主要是理论上的,所以如果它变得冗长,我道歉 背景 我正在从事的项目从其他网站(外部网站,而不是由我们托管)获取信息。我们希望获得尽可能接近实时的信息,以便向我们的用户提供即时相关的信息。这意味着要不断监视和更新表 很难展示我以前在这方面的工作,但在过去的几周里,我到处寻找“在数据库中维护实时数据”和“在发生外部更改时立即更新数据库”等类似内容。但一切都无济于事。我认为维护最新记录的问题很常见,所以我不确定为什么彻底解决这个问题似乎如此罕见 为了遵守SO的指导原则,我不是在征求意见,而是在寻找当前的最佳实践和业界最常用/公认的有效方法。 目前,使用PHP、MySQL、Cron高效维护大型表中当前/实时数据的方法?,php,mysql,sql-server,database,cron,Php,Mysql,Sql Server,Database,Cron,这主要是理论上的,所以如果它变得冗长,我道歉 背景 我正在从事的项目从其他网站(外部网站,而不是由我们托管)获取信息。我们希望获得尽可能接近实时的信息,以便向我们的用户提供即时相关的信息。这意味着要不断监视和更新表 很难展示我以前在这方面的工作,但在过去的几周里,我到处寻找“在数据库中维护实时数据”和“在发生外部更改时立即更新数据库”等类似内容。但一切都无济于事。我认为维护最新记录的问题很常见,所以我不确定为什么彻底解决这个问题似乎如此罕见 为了遵守SO的指导原则,我不是在征求意见,而是在寻找当
cron作业
,我们能做的最好的事情就是每分钟运行一个进程
* * * * * cd /home/.../public_html/.../ && /usr/bin/php .../robot.php >/dev/null 2>&1
问题是,我们正在从数千个其他站点(每行都是一个站点)提取数据,有时更新可能需要几分钟或更长时间。一分钟只调用一次函数是不够的。理想情况下,我们需要近乎即时的解决方案
检查行是否需要更新很快。基本上只是简单的哈希比较:
if(hash(current) != hash(previous)){
... update row ...
}
使用cron作业以独占方式触发的进程意味着,如果某一行最终得到更新,则该进程将被挂起,直到完成为止,或者直到cron作业在一分钟后触发新进程为止
不,布埃诺!拜!如果由于某种可怕的命运扭曲,每一行都需要更新,那么所有记录都可能需要数小时(或更长时间)才能更新。在那个时候,已经传递的行将过时
注意:数据库的设置方式使当前正在更新的行对新进程不可访问。该函数实质上是沿着表向下爬行,查找下一个尚未读取/更新的可用行,然后潜入。完成更新后,它将继续下一行
当每个进程到达表的末尾时,或者当表中的所有行都标记为已读时,就会终止该进程。此时,所有行都被重置为未读,流程重新开始
由于收集了大量数据,提高分辨率的唯一方法是同时运行多个进程
但是有多少是太多了
可能的解决方案(方法)
到目前为止,我提出的最好的方法是,尽快通过所有行,如下所示:
谢谢你陪我 首先,我读了所有内容!我不得不为此拍拍自己的背:) 您可能正在寻找的是工作队列。排队基本上就像你在超市里看到的那样,一个工作人员就是柜台上的女人,她接受钱,为每个顾客做一切。没有顾客时,她不工作,有顾客时,她工作 当商场里有很多顾客时,更多的工人会去空柜台,购买食品杂货的人会被分配给所有人 最近我写了很多关于队列的文章,我最推荐的是Beanstalk。它使用起来很简单,并且使用了PheanstalkA
<?php
$pheanstalk = new Pheanstalk('127.0.0.1:11300');
$pheanstalk
->useTube("my_queue")
->put("UPDATE mytable SET price = price + 4 WHERE stock = GOOG");//sql query for instance
?>
<?php
$pheanstalk = new Pheanstalk('127.0.0.1:11300');
if ($job = $pheanstalk
->watch('my_queue')
->ignore('default')
->reserve())//retreives the job if there is one in the queue
{
echo $job->getData();//instead of echoing you would
//have your query execute at this point
$pheanstalk->delete($job);//deletes the job from the queue
}
}
?>