不间断的 cronjob
Posted
技术标签:
【中文标题】不间断的 cronjob【英文标题】:Non-Stop cronjob 【发布时间】:2012-01-08 18:24:05 【问题描述】:我收到了企业关于“实时”数据/统计的新要求。他们想实时展示我们的系统是如何运行的。
我不知道该怎么做,但这是我的想法:
我认为不可能每秒钟都获取数据,因为 cronjob 至少每分钟运行一次。所以,我没有告诉他们,就说是的这是可能的。
现在我的问题是如何运行一个 cronjob 来获取我们网站上的统计信息(销售额、展示次数、每次点击费用等...)?
例子:
从上午 9 点到 9 点我有:
对产品 1 的 41 次浏览 1 个订单 来自客户的 8 次推荐点击 2 已添加到愿望清单从上午 9 点 02 分到上午 9 点 03 分我有:
产品 1 有 57 次浏览 0 订单 来自客户的 13 次推荐点击 0 添加到愿望清单总计:
产品 1 有 98 次浏览 1 个订单 来自客户的 21 次推荐点击 2 已添加到愿望清单如果由于某种原因数据库运行缓慢并且不能按时处理信息,我如何确保不会计算重复项?
谢谢
编辑:公司在 3 个不同的州拥有 200 名员工,其中包括销售人员、业务分析师、技术人员、会计人员和行政人员,这些人可以阅读这些报告。
去年我们雇佣了 20 名员工,因此会有所增长。对于交通数据,很难准确判断我们每分钟获得多少数据。估计约为每分钟 2.5k 到 10k。
我们刚刚订购了 3 个 PowerEdge R510(英特尔® 至强® E5503、2.0Ghz、4M 高速缓存、12GB 内存 (3x4GB)、1333MHz 双列、4 x 300GB 15K RPM 串行连接 SCSI 6Gbps RAID 5)。
【问题讨论】:
你有多少用户并且会增长?您每分钟获得多少数据?你有什么样的服务器(多少、速度、硬盘、内存)? 这些服务器是否仅用于报告?或用于其他目的? 不,我的想法是将 i 服务器 1 用于报告并使用当前的用于备份,2 用于我正在构建的新客户端系统(并使用旧的用于备份)负载平衡(并使用旧的备份) 【参考方案1】:如果这些服务器是,我根据您的服务器/员工/数据推荐以下内容。因为您使用的是 1 个服务器(和 1 个备份),所以驱动器的容量应该足够一段时间,除非您想在此服务器上存档完整的数据。数据可以快速增长,我会考虑增加容量或将数据归档到其他地方。
现在,因为您有很多人可以请求报告数据,所以主要想法是尽可能快地检索数据以确保您不会锁定记录(特别是如果您使用 myisam 表 - 表锁定与 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
拥有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
吨查询。
【讨论】:
感谢您的回答,这对我有帮助。是的,我知道,我的预算很紧。您能否详细说明:您的“汇总数据” 好吧,如果这不是一种常见的做法,我真的不在乎,我需要快速。你如何维护它? 我觉得我现在还可以,我明白你在说什么,我会试试看,谢谢你的帮助【参考方案2】:将记录的时间戳保存在数据库中,并根据它对数据进行评估(对于mysql http://dev.mysql.com/doc/refman/5.0/en/timestamp.html)
【讨论】:
您可以使用 fat-controller.sourceforge.net 每秒运行一次作业,或者在作业完成后不断重复作业,但我认为在这种情况下,使用 de3 天会好得多并为您的数据添加时间戳,然后使用 SQL 对其进行分组和聚合。 这个。您必须拥有数据上次更改状态的时间戳。否则,数据状态更改与您获取它的时间之间的任何延迟都会导致您的结果不准确。你如何归档这真的取决于你的能力和你的数据库的当前模式。您有任何可以利用的审计吗?【参考方案3】: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。
【讨论】:
我认为这样做不好。睡觉(10)?在高流量网站上? Aki,此建议仅适用于那些在私有服务器上运行的应用程序。否则,你也不能使用 max_execution_time。【参考方案4】:这听起来可能很奇怪,但是您为什么不使用 Google Analytics(分析)来执行此类跟踪任务。随着新的"live beta"
并使用其API 检索数据并执行管理层可能需要的所有奇特要求。
加上 js 和 google 将处理大部分负载。
edit:我真正的意思是,你为什么不尝试使用 js(woopra 或你自己的)来收集前端的点击、事件,并将所有统计信息存储在另一个数据库中,我不相信在任何生产服务器上混合 OLAP 和 OLTP 都是一个好主意。希望这是有道理的。
【讨论】:
我相信没有,除非 Google 没有更新其文档,否则实时测试版尚未进入 API 区域,因此最小过滤选项仍处于小时级别。我也更新了我的答案。以上是关于不间断的 cronjob的主要内容,如果未能解决你的问题,请参考以下文章