导读:本期聚焦于蜗牛创作的《Redis CountMinSketch是什么?如何用它高效估计元素频率?》,敬请观看详情。Count-Min Sketch是一种概率型数据结构,专门用来在海量数据中以极小的内存开销估计元素出现的次数。Redis从4.0开始通过布隆过滤器模块提供了CMS相关命令,让我们能够在Redis中直接构建频率统计能力。本文将详细讲解Count-Min Sketch的底层原理,包括二维计数数组、哈希函数个数与列宽对误差的影响,并给出在Redis中使用CMS.INCRBY、CMS.QUERY等命令的完整示例。同时对比它与HyperLogLog、精确计数方案的差异,分析误判只增不减的特性以及适合与不适合的业务场景,帮助你在限流、热点统计、TopK分析等场景中做出正确的技术选型。

在数据量动辄上亿的场景下,如果想统计某个元素出现过多少次,直接用Hash或String存储计数虽然精确,但内存开销会随元素种类线性增长,最终往往难以承受。Count-Min Sketch(简称CMS)正是为解决这类问题而生的概率型数据结构:它以固定的、可预先计算的内存空间,换取一个带误差上下界的频率估计值。Redis通过RedisBloom模块原生支持了Count-Min Sketch,使得我们可以在Redis中直接使用这一能力,而无需自己实现。

Redis CountMinSketch是什么?如何用它高效估计元素频率?

Count-Min Sketch的底层原理

Count-Min Sketch的核心是一个二维计数数组,假设有d行、每行w列,同时配套d个相互独立的哈希函数。当元素到来时,用d个哈希函数分别计算它落在每一行的列位置,并将对应位置上的计数器全部加一。查询时,同样计算d个哈希位置,取出d个计数值,取其中的最小值作为该元素的频率估计。

为什么取最小值?因为哈希冲突只会让计数变大,绝不会变小。也就是说,CMS的估计值永远满足两个特性:第一,估计值不会小于真实值,即只高不低;第二,误差有明确的上界。根据论文结论,如果将列数w设置为e除以epsilon向上取整,哈希函数个数d设置为ln(1除以delta)向上取整,则估计误差超过真实值加epsilon乘以总插入次数的概率不超过delta。

举个例子:设置width为2000、depth为5,用一个64位整数的计数器数组,总内存约为2000乘5乘8等于80000字节,也就是不到80KB。用不到80KB的空间就能支撑百万级不同元素的频率估计,这就是CMS相对于精确计数方案最大的魅力所在。

在Redis中使用CMS命令

RedisBloom模块从Redis 4.0起可以通过模块机制加载,其中包含了Count-Min Sketch的实现。常用命令有四个:CMS.INITBYPROB按误判概率初始化、CMS.INITBYDIM按维度初始化、CMS.INCRBY增加计数、CMS.QUERY查询估计值。使用前需确认模块已加载,可以用MODULE LIST命令查看。

# 按误差和置信度初始化,误差0.001,误判概率0.01
CMS.INITBYPROB cms:hot 0.001 0.01

# 或者直接指定宽度和深度
CMS.INITBYDIM cms:hot 2000 5

# 对元素增加计数,item1加5次,item2加3次
CMS.INCRBY cms:hot item1 5 item2 3

# 查询元素估计频率
CMS.QUERY cms:hot item1 item2

上面这段命令在redis-cli中执行后,CMS.QUERY会返回两个估计值。需要注意的是,CMS只支持增加计数,不支持减少。RedisBloom还提供了CMS.MERGE命令,可以把多个Sketch合并成一个新的,这在分片统计、多机房汇总的场景下非常实用。合并时可以指定每个来源的权重,例如把两个节点的热点数据加权汇总。

# 合并两个Sketch到新key,权重分别为1和3
CMS.MERGE cms:merged 2 cms:a cms:b WEIGHTS 1 3

# 查看sketch信息,返回width、depth和总计数
CMS.INFO cms:merged

与HyperLogLog及精确计数的对比

不少初学者容易把CMS和HyperLogLog混为一谈,实际上二者解决的问题完全不同。HyperLogLog回答的是基数问题,即有多少个不同的元素;CMS回答的是频率问题,即某个元素出现了多少次。前者无法告诉你某个具体元素的次数,后者可以近似做到。两者的内存都可以控制在KB级别,但CMS的内存由你指定的精度参数决定,HLL固定约12KB(标准误差约0.81%)。

方案内存结果特性支持删除
Hash精确计数随元素数线性增长精确支持
HyperLogLog约12KB基数估计,误差约0.81%不支持
Count-Min Sketch由精度参数决定,通常几十KB频率估计,只高不低不支持

精确Hash计数的优势是零误差且支持任意增删,适合元素种类可控、需要精确对账的业务,比如账户余额。而CMS适合元素种类极多、只需要近似值的统计场景。还要注意一个关键限制:CMS没有删除操作。如果业务存在元素下线或撤销计数的逻辑,CMS会带来无法修正的正向偏差,这种场景要么换精确方案,要么定期重建Sketch。

典型应用场景与选型建议

第一个典型场景是热点参数限流。比如对接口按用户ID或IP维度限流,不可能为每个IP都维护精确计数,用CMS估计访问频率,超过阈值就触发限流,即使有少量正向误差,也只是让限流略微偏严格,业务上完全可以接受。

第二个场景是热点key探测。在缓存架构中,及时发现访问量暴涨的key对容量规划很重要。可以在客户端埋点,把key访问写入CMS,再结合TopK扩展,就能低成本地识别出热点key并做本地缓存或分片处理。第三个场景是实时报表中的高频词、热门商品统计,这类场景天然接受近似值,且数据是只增的,与CMS的特性完美契合。

选型时有几点建议:第一,delta和epsilon要根据业务容忍度设置,精度每提高一个数量级,内存大约也增长一个数量级,不要盲目追求高精度;第二,depth一般取5到10即可,过多只会增加CPU开销而收益甚微;第三,如果数据流存在明显的时段性,建议按小时或按天滚动创建新的Sketch,用键名后缀区分,既避免了计数只增不减带来的长期偏差,也方便通过CMS.MERGE做周期性汇总。只要理解了它只高不低的误差特性和不可删除的限制,Count-Min Sketch就是海量频率统计场景下性价比极高的选择。

Redis CountMinSketchCount-Min Sketch布隆过滤器修改时间:2026-09-02 05:16:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。