在统计学中,聚合的定义指

使用基于多组观测结果的总结的统计替换多组观测结果 — 来自 https://web.archive.org/web/20120112062156/http://www.r-bloggers.com/aggregation-and-restructuring-data-from-%E2%80%9Cr-in-action%E2%80%9D/

预期的功能及实现

实现一个由分钟到年的聚合系统。

一、根据下一级数据聚合

比如小时的数据由分钟聚合,天的数据由小时聚合,周、月的数据由天聚合,年的数据由月聚合。

要求:

  • 下级数据存在
  • 选择正确的下级数据。比如月数据就不能由周数据聚合,而只能从天来聚合。

好处:
可以减少计算量。

二、数据完整

由于要根据下一级数据聚合,所以每个级别的数据都不能少。所以需要

  • 能够检测(各个级别的)数据完整
  • 能够幂等地重跑数据
  • 自动检测到数据不完整后,能自动地重跑数据

时区问题

一般的聚合都是基于时间的,比如从分钟以下聚合为分钟,然后小时,天,周,月,年等,所以就会有时区存在。

写入与查询

写入数据库的时间要带上时区。因为 MySQL、MongoDB 等数据库会将写入的 datetime 转化为 UTC 时区再储存,所以如果写入的时间没有带时区,数据库就会认为写入时间是 UTC 时区,可能会与你预期的不一致。

同理,查询时也要带上时区,因为数据库默认没有时区的时间为 UTC 时区。

聚合结果的时间储存

由于当前级别的数据是根据下一级数据聚合的,所以需要储存级别–时间类型以及时间。

时间类型为

  1. minutely
  2. hourly
  3. daily
  4. weekly
  5. monthly
  6. yearly

聚合时间为时间段的起点,我们把它叫做 time_start

"date_type" : "minutely", "time_start" : ISODate("2018-01-21T05:01:00Z")
"date_type" : "minutely", "time_start" : ISODate("2018-01-21T05:02:00Z")
...
"date_type" : "minutely", "time_start" : ISODate("2018-01-21T05:59:00Z")
// 根据以上的分钟数据聚合小时数据
"date_type" : "hourly", "time_start" : ISODate("2018-01-21T05:00:00Z")

多时区

由于在不同时区的每天的定义是不同的:

北京时间 07月31日为 “07月30日16:00:00 UTC — 07月31日16:00:00 UTC” 而东京则为 “07月30日15:00:00 UTC — 07月31日15:00:00 UTC”。

我目前的想法是再给聚合加上时区参数,但在本文不讨论聚合包含多时区问题,因为能用到的地方比较少。

聚合时机

聚合时机为当下一级别的数据不再变化时。一般来说,过去的数据是不会再变化的,所以我们聚合过去的数据:当前分钟聚合上一分钟的数据,当前小时聚合上一小时的数据,每月一号计算上一月的数据。

如果存在特殊情况导致要等待的久一些:比如由于网络延迟导致数据来的慢一些。我们也要进行调整:比如当前分钟聚合5分钟前的数据。

版权声明:本文为jay54520原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jay54520/p/8324273.html