Redis脚本那些事儿,玩着玩着功能就强大了,真没那么难
- 问答
- 2026-01-25 03:45:03
- 2
Redis脚本那些事儿,玩着玩着功能就强大了,真没那么难
很多人一听“Redis脚本”就觉得头大,感觉又是要学一门新语言,又是复杂的概念,其实完全不是那么回事儿,你可以把它理解成给Redis“打包”一系列指令的小工具,平时你发命令给Redis,都是一条一条来的,比如先GET一个值,再SET另一个值,但有些事儿,需要一连串操作,而且要求它们像一个人干活一样,不能被打断——这就是脚本大显身手的地方了。
Redis用的脚本语言叫Lua,别怕,你不需要成为Lua专家,就像你用计算器,不需要知道它里面芯片怎么造的一样,你只需要知道,用这个脚本,能把好几个Redis命令捆在一起,让它们原子性地执行(原子性就是说,这一捆命令要么全成功,要么全失败,不会执行到一半被别的命令插队),这是它最核心的魔法,为啥这很重要?举个例子:你要从一个账户扣钱,给另一个账户加钱,如果你先扣成功,还没来得及加的时候,系统去看账户总额,钱就“消失”了,用脚本把“扣”和“加”打包,外界看的时候,要么看到没扣也没加,要么看到扣了也加了,中间状态看不到,这就安全了。
(来源:Redis官方文档对EVAL命令的说明中,强调了Lua脚本在Redis中的执行是原子性的)
那这东西能玩出什么花样呢?玩法可多了,而且越玩越觉得顺手,你最常听到的“限流”,想限制一个用户1分钟内只能访问10次,不用脚本的话,逻辑挺啰嗦:要先查他访问了多少次,如果没超就加一次,如果超了就拒绝,这些操作分步进行,在高并发时容易出偏差,用脚本呢,你可以把这些逻辑(判断、计数)写在一个Lua脚本里,一次性发给Redis,Redis内部一气呵成地算完告诉你结果,又快又准,这就像你把一整张购物清单交给仓库管理员,他进去一趟把货配齐拿出来,比你自己跑进跑出十趟效率高多了。
再比如,处理秒杀库存,商品就100件,成千上万人来抢,脚本里的逻辑可以很简单:先判断库存是否大于0,大于0就减1,然后返回成功;否则返回失败,这个“判断-扣减”的动作在脚本里是不可分割的,这就完全避免了超卖,你可能会说,我用Redis的DECR命令不也能减吗?但DECR只能减,不能做到“只有大于0时才减”,脚本就把这个定制逻辑轻松实现了。
(来源:《Redis实战》一书中,在介绍“减库存”等模式时,明确推荐使用Lua脚本来保证操作的原子性和正确性)
还有更“玩”的,你可以用脚本实现复杂的计算,Redis虽然主要是存数据的,但有时候在数据存放的地方直接算好,比把数据传到外面算完再存回来,要快得多,也减轻了网络负担,比如你有一个排行榜,你想把某个用户的分数增加,同时更新他最新的修改时间,你可以写个脚本,接收用户ID和加分值作为参数,在脚本里一条执行ZINCRBY加分,另一条用HSET在另一个哈希表里记录时间,一次网络往返,两个操作都搞定。
你甚至可以用脚本玩出动态逻辑,根据不同的条件,给数据设置不同的过期时间,脚本里可以写if...else,根据传入的参数或者当前存在的某个值,来决定是设置5分钟过期还是永不过期,这种灵活性,是单纯发一条EXPIRE命令做不到的。
所以你看,学Redis脚本,一开始你根本不用去深究Lua语法多精妙,你就从一两个简单的需求开始:把两三条必须一起执行的命令包进去,你先用EVAL命令,直接把Lua代码写进去执行,等你熟悉了,可以把常用的脚本用SCRIPT LOAD命令永久加载到Redis里,它会返回给你一个“sha1”字符串的身份证,以后用这个身份证(用EVALSHA命令)来执行,连重复传代码都省了,效率更高。
(来源:Redis官方文档建议,对于常用脚本,应使用SCRIPT LOAD和EVALSHA来减少网络开销并提高效率)
说白了,Redis脚本就是一个让你把多个命令组合成一个定制命令的工具,它让Redis从一个简单的键值存储,变成了一个能执行你特定业务逻辑的“计算存储”,你玩着玩着就会发现,以前需要来回通信好几次、在程序里写一堆逻辑才能勉强完成的事儿,现在一个脚本丢给Redis就干净利落地解决了,功能自然就强大了,真没那么难,就从打包两个命令开始试试吧,一上手你就明白了。

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