前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一周技术学习笔记(第71期)-已经有200多个命令为何Redis还要Lua

一周技术学习笔记(第71期)-已经有200多个命令为何Redis还要Lua

作者头像
王新栋
发布2022-12-01 15:18:01
4340
发布2022-12-01 15:18:01
举报
文章被收录于专栏:程序架道程序架道

为什么要在Redis中使用Lua脚本

我们都知道Redis是一种高性能的key-value内存数据库,企业环境里面的很多应用场景都使用了它,因为在部分场景下它可以作为关系型数据库的补充,比如分布式缓存等。

在使用Redis的过程中我们接触了很多Redis的操作命令,它的官方网站上就提供了200多个命令,可以说”想怎么用就怎么用“,几乎涵盖了所有的kev-value操作。

不过,自从Redis2.6版本以后,在支持原有自身的操作命令的基础上,还增加了对Lua脚本命令的支持,原先的200多种命令还不够用吗?

在这么多的原生命令中,有不少原子性命令,比如INCR、DECR等,结合Redis单线程的”基因“,我们能够很容易的规避Read-Modify-Write带来的事务安全性问题。

但是呢,有些操作需要将若干个原子性命令合成一个的时候,Redis就无能为力了。

比如SET NX这个命令,我们常常用它来作为分布式锁,因为这个命令是在key不存在的情况下才能被SET成功,所以当多个请求去并发设置同一个key的时候,发现如果有进程已经SET成功了,就会导致SET失败,也就是获得锁失败,也就保证了只有一个请求进程能够获取到锁。

仅仅SET还不行,还必须有DEL,不然锁就会被一直拿着,当然你是可以为其设置超时时间的,但并不保险。

比如,有线程1、线程2和线程3这三个线程。如果线程1执行的时间较长没有来得及释放,锁就过期了,此时线程2是可以获取到锁的。当线程1执行完成之后,释放锁,实际上就把线程2的锁释放掉了。这个时候,线程3又是可以获取到锁的,而此时如果线程2执行完释放锁实际上就是释放的线程3设置的锁。

TIP:在DEL的时候可以通过对比VALUE值判断是否是同一个客户端来规避上述删除别人锁的现象。不过这里是说明客观上存在这样一个不安全的情况。

这种情况下,也就是说我们要把SET和DEL合并在一起使用,那就不是原子性的操作了。因为在SET和DEL之间会被其它线程插入的。

Redis意识到了上面的问题后,便推出了Lua脚本的功能。

这样,当我们遇到上述类似场景的时候,就可以把命令包装成一条Lua脚本命令,发送给Redis服务器。基于Redis服务器单线程来执行Lua脚本命令,就能够像执行原生的Redis命令那样,再也不会被其它请求打断了。

代码语言:javascript
复制
String luaScript = "local in = ARGV[1] local curr=redis.call('get', KEYS[1]) if in==curr then redis.call('del', KEYS[1]) end return 'OK'"";
 

----END----

这里记录,我每周碰到的,或想到的,引起触动,或感动的,事物的思考及笔记。不见得都对,但开始思考记录总是好的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序架道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档