不间断的克朗乔布斯

2022-08-30 17:49:00

我从业务部门获得了关于“实时”数据/统计数据的新要求。他们希望实时展示我们的系统如何表现。

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

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

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

例:

从上午9点01分到上午9点02分,我有:

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

从上午9点02分到上午9点03分,我有:

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

总:

  • 98 对产品 1 的浏览次数
  • 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)。


答案 1

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

现在,由于您有很多可以请求报告数据的人,因此主要思想是尽快检索数据,以确保您不会锁定记录(特别是如果您使用myisam表 - 表锁定与具有行级别锁定的innodb)。

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

您还可以做的是汇总数据,从而简化查询。虽然,在数据库中并不常见,因为它不尊重正常形式。您可以获得出色的性能,但维护起来很痛苦。

说实话,每分钟运行的cron是可以的,因为您在保存记录时有时间,但是每秒都可以获取数据。我建议确保在获得记录时,将此记录标记为“已处理”或其他状态,以免两次获取此记录。

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


编辑:汇总数据(不考虑数据库规范化)将获得出色的性能,因为您只查询记录而不使用聚合函数,并且使用最小 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周的数据,则必须创建一个合并表。通过这种方式,您可以执行如下操作:

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)


推荐