Redis秒级自增计数器的那些奇妙玩法,真没想到这么简单就能实现高效统计
- 问答
- 2026-01-04 07:00:50
- 18
前几天我在网上瞎逛,看到一个技术博客叫“程序员小灰”的,他讲了一个用Redis做秒级自增计数器的例子,我觉得特别有意思,原来我们平时觉得挺复杂的实时统计,用Redis来实现竟然可以这么简单,今天我就把他讲的,还有我自己想到的一些奇妙玩法,跟大家唠唠。
核心魔法:INCR命令
Redis秒级计数器的灵魂就是一个叫INCR的命令,这个命令特别直白,你就给它一个键(Key),比如叫page_view:20231027,它就会把这个键对应的数字自动加1,最关键的是,这个操作是“原子性”的,这个词听起来高大上,其实意思就是超级可靠,就算同一时刻有成千上万个用户同时点击,INCR命令也能保证每个点击都被准确无误地记上一次,绝对不会出现少记或者重复记的混乱情况,这就为我们做精准统计打下了最坚实的基础。
奇妙玩法大放送
有了INCR这个神器,我们能玩出什么花样呢?
玩法1:实时文章阅读量/商品点击量统计
这是最直接的应用,比如你的博客文章详情页,每次有人打开,就在后端执行一句:
INCR article:read:12345
这里的12345是文章的ID,就这么一句代码,这篇文章的阅读数就+1了,你想查的时候,再用GET article:read:12345命令把数字取出来显示就行了,简单到令人发指,而且速度极快,对数据库几乎没有压力,我记得“小林coding”在他的文章里也强调过,这种高频写、低频读的场景,用Redis是再合适不过了。
玩法2:限流与防刷——给操作上把锁
这个玩法非常实用,比如为了防止短信验证码被恶意频繁发送,我们可以这样做:当用户请求发送短信时,执行命令:
INCR sms_limit:13800138000
我们给这个键设置一个过期时间,比如60秒,用EXPIRE命令,然后我们检查这个键的值,如果在一分钟内,这个号码的计数值超过了5,就拒绝发送短信,到了下一分钟,这个键会自动过期删除,计数又从0开始,这样就实现了一个滑动时间窗口的限流,有效地防止了接口被刷。
玩法3:实现简易版“看过”功能
像B站那种“有多少人看过”的功能,用Redis也能轻松模拟,我们可以结合INCR和EXPIRE,用户第一次点击视频时,执行:
INCR video:view:88888
同时设置这个键在24小时后过期,这样,在24小时内,无论同一个用户看多少遍,都只算作一次有效观看(这里需要结合用户ID做更复杂的去重,但核心计数思想是一样的),这个简单的模型可以帮助我们统计短时间内的独立热度。
玩法4:生成分布式环境下的唯一订单号
在分布式系统里,多个机器同时要生成订单号,怎么保证不重复呢?Redis可以当做一个全局唯一的序号生成器,我们可以这样做:用当天的日期作为一个Key,比如order_id:20231027,然后每次生成订单前,执行:
INCR order_id:20231027
这个命令返回的数字,比如是10086,那我们今天的订单号就可以拼成202310270010086,这样既保证了顺序,又在分布式环境下绝对唯一,非常巧妙。
玩法5:实时在线用户数估算
虽然不是精确统计,但可以做个大概的估算,思路是:当用户上线时,我们以秒级精度创建一个Key,比如user_online:20231027:10:30:01,然后执行INCR,设置这个Key在2分钟后过期,我们想统计当前在线人数时,只需要计算最近2分钟内所有秒级Key的数值总和就可以了,虽然有点误差,但对于实时大屏显示“当前在线人数”这种场景,已经完全够用了,而且性能消耗极小。
为什么这么高效?
其实道理很简单,传统数据库(比如MySQL)每次做UPDATE table SET count=count+1这种操作,都要经历复杂的磁盘读写和事务锁机制,在超高并发下很容易成为瓶颈,而Redis的所有数据都放在内存里,操作速度本身就是硬盘的几十上百倍,再加上INCR这种原子操作天生就避免了锁竞争,所以才能轻松应对每秒数万甚至数十万的计数请求。
Redis的秒级自增计数器就像一把瑞士军刀,看起来简单,但用起来却能解决很多看似复杂的实时统计问题,它背后的思想就是:用空间(内存)换时间(速度),用简单的原子操作保障高并发下的数据准确性,下次当你遇到需要实时计数、限流或者生成唯一ID的场景时,不妨先想想这把“瑞士军刀”,说不定能省下你很多功夫。

本文由盈壮于2026-01-04发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/74181.html
