不停的cronjob

时间:2011-11-29 11:59:04

标签: php mysql cron duplicates

我从业务中得到了关于“实时”数据/统计数据的新要求。他们想要展示我们的系统如何实时运行。

我不知道该怎么做,但这是我的想法:

我不认为每秒钟都可以获取数据,因为cronjob至少每分钟运行一次。所以,在没有告诉他们的情况下,我说这是可能的。

现在我的问题是如何运行一个cronjob来获取我们网站的统计数据(销售额,印象数,cpc等等)?

示例:

从上午9点到凌晨9点,我有:

  • 关于产品1的41次浏览
  • 1个订单
  • 8个推荐点击来自客户
  • 2添加到愿望清单

从早上9点到早上9点03分,我有:

  • 产品1的57次浏览
  • 0 order
  • 13个推荐点击来自客户
  • 0已添加到愿望清单

总数:

  • 关于产品1的98次浏览
  • 1个订单
  • 21来自客户的推荐
  • 2添加到愿望清单

如果由于某种原因数据库速度慢并且不按时处理信息,我如何确保不会计算重复项?

由于

编辑:该公司在3个不同的州拥有200名员工,其中包括销售,业务分析师,技术,会计和执行人员,这些人可以阅读这些报告。

去年我们雇用了20名员工,因此会有所增长。对于流量数据,很难确切地说出我们每分钟获得的数据量。估计约为每分钟2.5k至10k。

我们刚刚订购了3台PowerEdge R510(Intel®Xeon®E5503,2.0Ghz,4M Cache,12GB内存(3x4GB),1333MHz双列,4 x 300GB 15K RPM串行连接SCSI 6Gbps RAID 5)。

4 个答案:

答案 0 :(得分:30)

如果这些服务器是基于您的服务器/员工/数据,我推荐的。由于您使用的是1台服务器(和1台备份),因此驱动器的容量应该足够一段时间,除非您要在此服务器上存档完整数据。数据可以快速增长,我认为可以增加容量或将数据存档到其他地方。

现在,因为你有很多人可以请求报告数据,主要的想法是尽可能快地检索数据,以确保你不锁定记录(特别是如果你使用myisam表 - 表锁定vs innodb有行级锁定)。

明智地使用您的索引(如果需要,可以使用您的索引)并使用时间戳尽可能高效地存储数据。

您还可以做的是总结您的数据,这可以简化您的查询。虽然,在数据库中不常见,因为它不尊重正常形式。你可以获得很好的表现但是维持起来很痛苦。

老实说,每分钟运行一次的cron很好,因为你有时间保存记录但是每秒都可以得到数据。我建议您确保在获得记录时,将此记录标记为“已处理”或其他一些状态,以便您不会将此记录两次。

现在,当您汇总数据时,请确保优化查询,并且还可以检查explain将输出的内容然后做出决定。


编辑:汇总数据(不考虑数据库规范化)将为您提供出色的性能,因为您只使用聚合函数查询记录并使用最小的where子句连接表。

示例:

98 views on product 1
1 order
21 referral click from clients
2 added to wishlist

可以是:

SELECT
 views, orders, referral, whishlist
FROM
 summarize_stats_20111201 /* daily table for example */
WHERE
 `time` between 1322791200 /*2011-12-01 21:00:00*/ AND 1322791260 /*2011-12-01 21:01:00*/;

views包含总观看次数,在此示例中为98

orders包含订单总额,在此示例中为1

referral具有推介总量,​​在此示例中为21

wishlist具有心愿单总数,在此示例中为2

这些是汇总表中的计算数据(这就是为什么我说“不尊重数据库规范化”,因为你从不计算RDBMS中的数据)但是如果你需要立即获得数据,这是你可以做到的一种方式。


编辑2: 以下是维护此解决方案的示例:

你有一个维护表格的cronjob。他的工作是为第二天或任何你需要的东西创造桌子。

// in php
$date = date('Ymd', strtotime('+1 day')); // for daily table 
$sql = 'CREATE TABLE IF NOT EXISTS the_database.summarize_stats_" . $date . ";

因此,当您插入时,请确保您拥有正确的表名,并使用ON DUPLICATE KEY

// in php
$sql = 'INSERT INTO TABLE summarize_stats_20111201 SET /* all the fields you need */ ON DUPLICATE KEY views = views + 1;

例如,如果你想增加视图

我还忘记的是,如果您需要查询1周的数据,则必须创建merge表。通过这种方式,您可以执行以下操作:

SELECT
 views, orders, referral, whishlist
FROM
 summarize_stats_2011 /* yearly merge table for example */
WHERE
 `time` between 1322272800 /*2011-11-25 21:00:00*/ AND 1322791260 /*2011-12-01 21:01:00*/;

这样您就不需要UNION ALL吨查询。

答案 1 :(得分:2)

在数据库中保存记录的时间戳,并根据它评估数据(对于mysql http://dev.mysql.com/doc/refman/5.0/en/timestamp.html

答案 2 :(得分:0)

Gino,如果您可以访问服务器上的php.ini,则可以执行类似cronjobs的操作。如果你可以将max_execution_time的值设置为零,你可以创建自己的每秒运行的cronjobs。你需要的是你的php.ini:

max_execution_time = 0

或将其设置为PHP代码中的运行时脚本:

ini_set("max_execution_time",0); 

您需要的下一个功能是PHP中的sleep()函数。 此功能会延迟您的操作。您可以像sleep(10);一样使用它。 有关此功能的更多信息,请查看this link

答案 3 :(得分:0)

这可能听起来很奇怪,但为什么不使用Google Analytics进行此类跟踪任务。使用新的"live beta"

使用API检索数据,并执行管理层可能需要的所有花哨要求。

加上js和谷歌将处理大部分负担。

编辑:我的真正观点是你为什么不尝试使用js(woopra或你自己的)来收集前端的点击,事件,并将所有统计数据存储在另一个数据库中,我不知道我相信在任何生产服务器上混合使用OLAP和OLTP都是一个好主意。希望有意义。