下载量统计:滑动窗口 vs 整点分桶与 Redis 分钟桶方案

两种统计方式

滑动窗口(实时系统首选)

统计”当前往前推 N 小时”的下载数:

-- 1 小时下载量
SELECT COUNT(*) FROM downloads
WHERE download_time >= NOW() - INTERVAL 1 HOUR;

-- 3 小时下载量
SELECT COUNT(*) FROM downloads
WHERE download_time >= NOW() - INTERVAL 3 HOUR;

特点:平滑、不会整点突变,适合实时热榜、推荐系统、CDN 统计。

自然时间段(BI 报表常用)

按整点分桶,例如现在 15:37,统计范围是 15:00~15:59:

SELECT COUNT(*) FROM downloads
WHERE HOUR(download_time) = HOUR(NOW())
  AND DATE(download_time) = CURDATE();

适合财务报表、数据仓库场景,不适合实时排行——整点会出现排名抽搐。

Redis 分钟桶(高并发推荐)

生产环境不会每次扫大表,而是用 Redis 分钟桶:

Key 格式:download:item:{id}:{yyyyMMddHHmm}
例如:download:item:123:202605281537

每次下载:

INCR download:item:123:202605281537
EXPIRE download:item:123:202605281537 86400

查询 1 小时:累加最近 60 个分钟 Key 查询 3 小时:累加最近 180 个分钟 Key

逻辑上是滑动窗口,底层是时间桶——抖音、B站、Steam 热榜的标准做法。

热度分值

单纯看 1 小时容易被刷量,实际排行榜通常组合多个时间窗口:

score = download_1h  * 0.5
      + download_3h  * 0.3
      + download_24h * 0.2

再叠加时间衰减因子防止老内容永远霸榜。

方案选型

场景推荐方案
普通业务后台MySQL NOW() - INTERVAL
高并发下载统计Redis 分钟桶 + 定时汇总
热门排序1h + 3h + 24h 三个窗口组合
历史分析 / BIClickHouse 聚合