统计与计费
参考金山云文档:https://docs.ksyun.com/documents/223?type=3
上游提供的能力如下:
- 最多可获取最近一年内93天跨度的数据
- 统计粒度:5分钟粒度;10分钟粒度;20分钟粒度;1小时粒度;4小时粒度;8小时粒度;1天粒度;以上粒度流量值均取该粒度时间段的流量之和
- 时效性:5分钟延迟
- 接口性能:接口最大吞吐量为10000,
- 单次查询域名数量不得超过1000个,且单次查询时间跨度至少包含一个时间粒度点
统计
鉴于我们在展示流量统计数据的时候是按天来选择时间段的,因此,不管是哪个颗粒度,每天的数据都只存一条记录,所有颗粒度的数据作为数组放在一个字段中(例如字段名为 data)。
步骤(以5分钟颗粒度为例,即每天有 288 个颗粒度):
- 查询所有域名,检查每个域名的最后拉取数据的时间,如果最后拉取时间在当天范围内(例如 1月 8号的 0 时到 24时之间),则每34个域名为一组拉取当天的数据(34 X 288 = 9792颗粒 < 10000)
- 将拉取到的数据按照每个域名一个条目暂存在 redis 中
- 每日凌晨10分之后,查询一次前一天的数据并插入数据库
- 如果拉取时间不在当天范围内,则以每个域名每34天(不包含当天)(34 X 288 = 9792颗粒 < 10000)作为一个时间段查询其该时间段内的数据,并将数据按照每天一个条目插入到数据库中
- 查询数据时,不要忘了当天的数据是在 redis 缓存中的
以此类推 10 分钟、1小时、1天颗粒度。
统计数据的存储方式
鉴于上游给我们保留的数据是93天的时间窗口,也就是能看到3个月的数据,因此我们给用户也保留3个月的数据窗口,超出3个月的数据我们可以选择删除或导出文件并存在硬盘上。
为了便于将超过时间窗口的数据删除,我们可以在数据库中按月创建数据表,每个数据表只保存对应月份的数据,这样在删除数据时就可以直接删表,速度很快。因此,我们可以预先创建120个月(10年)的数据表,以免忘了。
如果需要保留数据,可以按月将数据表导出为文件并存于硬盘或云存储上。
对外提供统计数据
由于每个域名每天的统计数据都存放在一条记录中,因此,根据外部查询给出的时间段范围从同一或不同月份的数据表中拿到数据后回吐即可。前台在展示统计数据时要根据数据的颗粒度自行将数据对应到每个颗粒的时间点上(例如,5分钟颗粒度下,每天的时间点是 00:05、00:10、00:15......24:00)。再次提醒:当日的数据在redis缓存中!
计费
鉴于计费时我们需要尽快查询到最小颗粒度的流量并尽快扣费,因此所有为计费任务而拉取的统计数据都不保存。
5分钟颗粒度计费步骤:
术语定义:
- 最后计费时间:最后一个计费颗粒度的时间,即分钟数能被 5 整除的时间。即便没有数据也要记录
- 查询所有域名,检查每个域名的最后计费时间,如果最后计费时间距当前时间大于 50 分钟(10000 / 1000 * 5 = 50分钟),则按每个域名拉取从上次计费时间到当前时间的所有数据,
- 拉取最后计费时间到当前时间的数据时,按照每34天(34 X 288 = 9792颗粒 < 10000)拉取一次,避免超出上游限制
- 如果最后计费时间距离当前时间小于 50 分钟,则按每 1000 个域名查询一次,
- 每次拉取数据后,保留最新鲜的5个颗粒度的数据看作不稳定数据并做预先扣费,等下次拉取数据时,前次遗留的5个颗粒度数据和新数据按时间点合并,并且新数据覆盖遗留的数据,合并后的数据仍然保留最新鲜的5个颗粒度的数据看作不稳定数据,其余数据直接扣费。以此循环。
注:扣费时,数据稳定且能直接扣费的,直接从 User 表中的 cdnBalance 字段中扣费;预扣费的部分,User 表中会利用一个字段 cdnFrozenBalance 保存预扣费数据,cdnBalance 不变。