当前位置:首页 > 问答 > 正文

用Redis搞个自增计数,感觉挺方便的,就是那个值一直往上加那种功能

(用Redis搞个自增计数,感觉挺方便的,就是那个值一直往上加那种功能)

用Redis搞个自增计数,感觉挺方便的,就是那个值一直往上加那种功能

这事儿说起来挺简单的,就是想找个地方存个数字,然后每次需要的时候,能让这个数字自己加1,比如给文章数数阅读量啊,给用户生成个唯一的订单号啊,或者就是单纯看看某个活动被点击了多少次,以前可能得在数据库里建张表,专门有个字段来存这个数,每次更新还得先查出来,再加1,再写回去,生怕同时好几个人操作给搞乱了,麻烦得很。

用Redis搞个自增计数,感觉挺方便的,就是那个值一直往上加那种功能

后来听人说Redis干这个特别在行,它里头有个命令就叫INCR,就是专门干这个“自增”活儿的,我一试,还真是,方便得不得了,你不用管它现在是多少,就直接发个INCR key的命令过去,它立马就给你返回一个加了1以后的新数字,关键是,它自己保证这个操作是原子的,这个词儿听着专业,说白了就是“不可分割”,同一时刻就算有一万个人同时对同一个key发INCR命令,Redis也会排着队一个个给你处理,绝对不会出现两个人拿到同一个数的情况,这个数肯定是蹭蹭地往上走,一点都不会乱,这就解决了大问题,不用我们自己费劲去加锁啥的,省心。

用Redis搞个自增计数,感觉挺方便的,就是那个值一直往上加那种功能

比如说,我想给我的博客文章统计阅读量,每篇文章我给分配一个唯一的key,比如article:123:views,其中的123就是文章的ID,每次有个人打开这篇文章,我就在程序里执行一句 INCR article:123:views,第一次执行,这个key本来不存在,Redis会把它当成0来处理,然后返回1,第二次执行返回2,就这么一直累加下去,我想看现在有多少阅读量了,不用执行INCR,用个GET article:123:views命令就能直接把当前的数字读出来,特别直观。

光能加1还不够,有时候需求会复杂点,比如我想一次性加个5,或者减个1,Redis也想到了,有INCRBY key increment命令,你想加几就在后面写几,比如INCRBY article:123:views 5,阅读量瞬间涨5个,要是想减,就用DECR key减1,或者DECRBY key decrement减指定的数,这些操作跟INCR一样,都是原子的,很稳妥。

还有个挺常见的场景是生成订单号,我们不想用数据库那个自己增长的ID,想用年月日加上一个当天内自增的序列号,202405210001”这种格式,用Redis也能轻松搞定,我可以设置一个key,比如叫order:id:20240521,代表2024年5月21这天的订单序列,每次要生成新订单号的时候,就先执行一下 INCR order:id:20240521,假设得到数字1,我就在程序里拼凑成“202405210001”,第二天,key变成order:id:20240522,再从1开始累加,这样每天都能重新开始,而且序列号绝对不会重复,不过这里要注意,像订单号这种key,通常都是有时效性的,过了一天就没用了,所以最好给它设置个过期时间,比如24小时或者36小时后自动删除,省得积累一大堆没用的key,占着内存,用EXPIRE key seconds命令就能设置。

用了Redis这个自增功能之后,感觉确实轻快,它是在内存里操作的,速度非常快,比去读写数据库磁盘要快太多了,对于这种频繁更新、但数据本身又不算特别重要的计数场景,简直是绝配,当然啦,也得心里有数,Redis的数据默认是存在内存里的,万一服务器重启了,数据可能就丢了(除非你开启了持久化功能),所以像阅读量这种丢一点勉强还能接受,但如果是非常重要的、绝对不能错的序号,就得好好考虑一下持久化配置,或者想别的更保险的招儿了,对于大部分“就是想看着数字往上涨”的需求,Redis的INCR系列命令绝对是首选,简单、粗暴、有效。