Redis 命令及数据类型 -- TopK
摘要
- 本文介绍 Redis 扩展模型 RedisBloom 中的 TopK 数据类型
- 本文基于
redis-7.4.7,springboot-3.5.8 - Redis官网:https://redis.io/
- Redis 命令文档:https://redis.io/docs/latest/commands/
- RedisBloom 的安装参见 Redis 扩展模块 -- RedisBloom
TopK
-
TopK,专门用于解决 “在海量数据流中,实时找出最热门的 N 个元素” 这一类问题
-
Top-K 属于流式重频(Heavy Hitters)算法家族,其目标不是记录所有元素,而是:
- 在受限内存下,持续维护出现频率最高的 K 个元素
-
TopK 的核心特性
1 | 固定容量:只维护 K 个元素 |
-
RedisBloom 的 TopK 内部使用 CMS 作为频次估算基础,并结合
堆+淘汰策略来维护热点集合。- CMS: 参考 Redis 命令及数据类型 -- CMS(Count-Min Sketch)
- 堆+淘汰策略: TopK 在内部如何决定谁能进入 TopK、谁必须被踢出 TopK 的一整套机制。
- 堆:TopK 使用一个最小堆来维护 TopK 元素,TopK 维护 K 个候选元素,堆顶永远是 当前 TopK 中频次最低的那个
- 淘汰策略:TopK 使用一个 LRU 缓存来记录最近访问的元素,当 TopK 元素数量达到上限时,将 LRU 缓存中的元素逐个加入 TopK,并更新 TopK 元素的频率。
- 一句话:当新元素的估算频次超过当前最弱的那个时,就把弱者淘汰掉,让新元素进榜。
当一个新元素到来时,我该不该让它进入 TopK?
-
下面是 TopK 在 TOPK.ADD 时的真实逻辑抽象
1 | # Step 1:更新 CMS(不存 item,只更新计数器) |
TopK 的应用场景
| 问题 | TopK 是否适合 |
|---|---|
| 当前访问量最高的 URL | ✅ |
| 搜索热词 Top 10 | ✅ |
| 商品点击榜 | ✅ |
| 所有商品的点击次数 | ❌ |
| 精确计数 | ❌ |
RedisBloom TopK 的核心命令
创建 TopK
-
使用 TopK 前必须先创建 TopK
1 | # TOPK.RESERVE key topk [width depth decay] |
添加元素
1 | # TOPK.ADD key items [items ...] |
增加元素的频率
1 | # TOPK.INCRBY key item increment [item increment ...] |
查询元素是否在 TopK 中
1 | # TOPK.QUERY key item [item ...] |
获取 TopK 中的元素
1 | # TOPK.LIST key [WITHCOUNT] |
获取近似计数
1 | # TOPK.COUNT key item [item ...] |
查看TopK 的状态
1 | # TOPK.INFO key |
TopK 的衰减(decay)参数怎么理解
-
decay 用于解决一个问题:“老热点永远霸榜,新热点上不来”
| decay | 行为 |
|---|---|
| 1.0 | 永不衰减(全历史统计) |
| 0.9 | 越老的数据权重越低 |
| 0.5 | 热点更新非常快 |
-
经验值:
- 实时热点:0.8 ~ 0.9
- 长周期榜单:0.95 ~ 1.0
CMS 和 TopK 组合使用场景
📌场景1: 实时热搜榜(最经典组合)
-
需求:统计所有搜索词频次(CMS),同时实时出TOP10热搜(TOPK),既知热度又能排序
1 | # 1. 初始化CMS(统计全量搜索词计数,误差0.001) |