我从业务中得到了关于“实时”数据/统计数据的新要求。他们想要展示我们的系统如何实时运行。
我不知道该怎么做,但这是我的想法:
我不认为每秒钟都可以获取数据,因为cronjob至少每分钟运行一次。所以,在没有告诉他们的情况下,我说是这是可能的。
现在我的问题是如何运行一个cronjob来获取我们网站的统计数据(销售额,印象数,cpc等等)?
示例:的
从上午9点到凌晨9点,我有:
从早上9点到早上9点03分,我有:
总数:
如果由于某种原因数据库速度慢并且不按时处理信息,我如何确保不会计算重复项?
由于
编辑:该公司在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)。
答案 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都是一个好主意。希望有意义。