我从企业那里得到了关于“实时”数据/统计的新要求。他们想实时展示我们的系统如何运行。
我不确定该怎么做,但这是我的想法:
我认为不可能每秒都获取数据,因为 cronjob 至少每分钟运行一次。所以,我没有告诉他们,就说是这是可能的。
现在我的问题是如何运行一个 cronjob 来获取我们网站的统计信息(销售额、展示次数、每次点击费用等...)?
示例:
从 9h01 AM 到 9h02AM 我有:
- 产品 1 有 41 次浏览
- 1 个订单
- 8 次来自客户的推荐点击
- 2 添加到愿望 list
从 9h02AM 到 9h03AM 我有:
- 对产品 1 的 57 次浏览
- 0 订单
- 13 次来自客户的推荐点击
- 0 添加到愿望 list
总计:
- 产品 1 有 98 次浏览
- 1 个订单
- 21 次来自客户的推荐点击
- 2 添加到愿望 list
如果由于某种原因数据库很慢并且没有及时处理信息,我如何确保我不会计算重复项?
谢谢
编辑:该公司在 3 个不同的州拥有 200 名员工,其中包括销售人员、业务分析师、技术人员、会计人员和执行人员,这些人可以阅读这些报告。
去年我们雇用了 20 名员工,因此它会有所增长。对于交通数据,很难准确判断我们每分钟获得多少数据。估计约为每分钟 2.5k 至 10k。
我们刚刚订购了 3 个 PowerEdge R510(Intel® Xeon® E5503、2.0Ghz、4M 高速缓存、12GB 内存 (3x4GB)、1333MHz 双列、4 x 300GB 15K RPM 串行连接 SCSI 6Gbps RAID 5)。
最佳答案
以下是我根据您的服务器/员工/数据推荐的内容(如果这些服务器是的话)。因为你使用的是 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。他的工作是为第二天或您需要的任何东西制作餐 table 。
// 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;
例如如果你想增加 View
我还忘记了,如果您需要查询 1 周的数据,则必须创建一个 merge table 。这样你就可以做类似的事情:
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
大量查询。
关于php - 不间断的cronjob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8310321/