redis分布式锁lua脚本(Redis 中使用 Lua 脚本)

:暂无数据 2026-08-24 20:20:14 :1

redis分布式锁lua脚本(Redis 中使用 Lua 脚本)

大家好,今天小编来为大家解答以下的问题,关于redis分布式锁lua脚本,Redis 中使用 Lua 脚本这个很多人还不知道,现在让我们一起来看看吧!

本文目录

Redis 中使用 Lua 脚本

Redis 本身已经提供了丰富的命令,但是直接用来处理一些复杂业务时可能还不够方便,会有一定的局限性。因此,在 Redis2.6 版本开始提供了对 Lua 脚本的支持,Lua 脚本的使用还是比较广泛的,比如商品秒杀、分布式锁等,使用 Lua 脚本可以带来以下的好处:

为了让例子更加的贴近实际应用,这里实现一个简单版的分布式锁。这里先用 Jedis 操作。

上边详细的介绍了分布式锁的实现过程,以及可能出现的问题,最终,我们决定删除锁的操作使用 Lua 脚本实现,对应的脚本如下:

Lua 脚本中执行具体的 Redis 命令,需要使用 redis.call() 方法, KEYS 表示客户端发起脚本执行命令时携带的 Redis key 的一个集合, ARGV 则是其它参数的一个集合,主意下标从1开始。结合我们的业务,这里的 KEYS 则是一个随机字符串。整个脚本的含义就是,如果客户端传递的 lock 的 value 和 Redis 中存储的一致,就删除 lock 。

Lua 脚本的语法还是比较简单的,具体内容可以自行学习。

前边的准备工作基本结束了,文章开始说过执行脚本有两种途径,下边我们具体来看:

这里使用 jedis.eval() 发送脚本到 Redis 服务器执行,后两个参数分别是 key 的集合,以及 value 参数的集合。

先将脚本以文件形式放到 Redis 里,例如这样:

然后通过如下命令让 Redis 服务器缓存脚本:

script load 命令会在 Redis 服务器缓存 Lua 脚本,并且脚本内容经过 SHA-1 签名算法处理后,会返回脚本内容的 SHA1 校验和的编码,然后在端调用时,传入编码字符串作为参数,这样 Redis 服务器就会执行对应缓存的脚本了,就不用了每次发送具体的脚本内容了。

还有两个比较有用的命令:

除了使用上边的命令缓存脚本、生成脚本的 SHA1 校验和的编码,还可以使用 Jedis 实现,但最终的 SHA1 编码内容是不同的:

实际的项目中,可能更多的会在 SpringBoot 项目中整合 Redis,此时执行 Lua 脚本的基本流程如下:

核心的类就是 DefaultRedisScript ,它实现了 RedisScript 接口。 execute() 方法最后一个参数是可变类型的,用来传递多个 value 参数。初次执行 execute() 方法时,其内部会自动缓存 Lua 脚本到 Redis 服务器;同时每次执行脚本时会根据脚本内容自动计算出对应的 SHA1 校验和的编码,去匹配、执行缓存的脚本。

具体的 SHA1 校验和的编码,可以在 execute() 方法执行后,使用 redisScript.getSha1() 查看。使用 SpringBoot 方式 执行 Lua 脚本生成的 SHA1 校验和的编码和前边直接使用 Jedis 生成的一致。

无论用那种方式在 Redis 中使用 Lua 脚本,其中的原理都是类似的。

分布式锁有哪些

单体架构的应用可以直接使用synchronized或者ReentrantLock就可以解决多线程资源竞争的问题。如果公司业务发展较快,可以通过部署多个服务节点来提高系统的并行处理能力。由于本地锁的作用范围只限于当前应用的线程。高并发场景下,集群中某个应用的本地锁并不会对其它应用的资源访问产生互斥,就会产生数据不一致的问题,所以分布锁就派上了用场。

利用select … where … for update 排他锁

所谓乐观锁与前边最大区别在于基于CAS思想,是不具有互斥性,不会产生锁等待而消耗资源,操作过程中认为不存在并发冲突,只有update version失败后才能觉察到。我们的抢购、秒杀就是用了这种实现以防止超卖。通过增加递增的版本号字段实现乐观锁

思路: 另启一个服务,利用jdk并发工具来控制唯一资源,如在服务中维护一个concurrentHashMap,其他服务对某个key请求锁时,通过该服务暴露的端口,以网络通信的方式发送消息,服务端解析这个消息,将concurrentHashMap中的key对应值设为true,分布式锁请求成功,可以采用基于netty通信调用,当然你想用java的bio、nio或者整合dubbo、spring cloud feign来实现通信也没问题

在高并发场景下,应用程序在执行过程中往往会受到网络、CPU、内存等因素的影响,所以实现一个线程安全的分布式组件,往往需要考虑很多case,这个分布式锁有 3 个重要的考量点:

下面是redis分布式锁的各种实现方式和缺点,按照时间的发展排序:

直接利用setnx,执行完业务逻辑后调用del释放锁,简单粗暴!

为了改正第一个方法的缺陷,我们用setnx获取锁,然后用expire对其设置一个过期时间,如果服务挂了,过期时间一到自动释放

redis官方为了解决第二种方式存在的缺点,在2.8版本为set指令添加了扩展参数nx和ex,保证了setnx+expire的原子性,使用方法:set key value ex 5 nx

上面所说的第一个缺点,没有特别好的解决方法,只能把过期时间尽量设置的长一点,并且最好不要执行耗时任务 第二个缺点,可以理解为当前线程有可能会释放其他线程的锁,那么问题就转换为保证线程只能释放当前线程持有的锁,即setnx的时候将value设为任务的唯一id,释放的时候先get key比较一下value是否与当前的id相同,是则释放,否则抛异常回滚,其实也是变相地解决了第一个问题

我们可以用lua来写一个getkey并比较的脚本,jedis/luttce/redisson对lua脚本都有很好的支持

为了解决上面提到的redis集群中的分布式锁问题,redis的作者antirez的提出了red lock的概念,假设集群中所有的n个master节点完全独立,并且没有主从同步,此时对所有的节点都去setnx,并且设置一个请求过期时间re和锁的过期时间le,同时re必须小于le(可以理解,不然请求3秒才拿到锁,而锁的过期时间只有1秒也太蠢了),此时如果有n / 2 + 1个节点成功拿到锁,此次分布式锁就算申请成功

ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名。基于ZooKeeper实现分布式锁的步骤如下:

(1)redis set px nx + 唯一id + lua脚本

综上所得:

没有绝对完美的实现方式,具体要选择哪一种分布式锁,需要结合每一种锁的优缺点和业务特点而定。

Redis 中使用 Lua 脚本的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于Redis 中使用 Lua 脚本、Redis 中使用 Lua 脚本的信息别忘了在本站进行查找哦。

redis分布式锁lua脚本(Redis 中使用 Lua 脚本)

本文编辑:admin

更多文章:


jstl标签前缀为fmt(Fmt标签要导入的包是)

jstl标签前缀为fmt(Fmt标签要导入的包是)

大家好,如果您还对jstl标签前缀为fmt不太了解,没有关系,今天就由本站为大家分享jstl标签前缀为fmt的知识,包括Fmt标签要导入的包是的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

2026年10月10日 16:50

tcp ip四层网络模型(TCP IP参考模型共分为四层:(  )、网络层、传输层、应用层)

tcp ip四层网络模型(TCP IP参考模型共分为四层:(  )、网络层、传输层、应用层)

大家好,如果您还对tcp ip四层网络模型不太了解,没有关系,今天就由本站为大家分享tcp ip四层网络模型的知识,包括TCP IP参考模型共分为四层:(  )、网络层、传输层、应用层的问题都会给大家分析到,还望可以解决大家的问题,下面我们

2026年10月10日 15:20

c 数组排序(c语言对一维数组排序)

c 数组排序(c语言对一维数组排序)

这篇文章给大家聊聊关于c 数组排序,以及c语言对一维数组排序对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

2026年10月10日 14:50

sql server数据库管理系统是基于(MS-SQL 是甚麼)

sql server数据库管理系统是基于(MS-SQL 是甚麼)

各位老铁们,大家好,今天由我来为大家分享sql server数据库管理系统是基于,以及MS-SQL 是甚麼的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

2026年10月10日 14:40

微服务架构项目实例(微服务架构之「 容器技术 」)

微服务架构项目实例(微服务架构之「 容器技术 」)

大家好,微服务架构项目实例相信很多的网友都不是很明白,包括微服务架构之「 容器技术 」也是一样,不过没有关系,接下来就来为大家分享关于微服务架构项目实例和微服务架构之「 容器技术 」的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我

2026年10月10日 12:40

component什么意思(Component是什么意思)

component什么意思(Component是什么意思)

大家好,关于component什么意思很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于Component是什么意思的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助

2026年10月10日 09:40

svga转动图(svga后缀名的动图用什么软件观看我在https://svga.io/svga-preview.html网站上看没声音啊,求指点)

svga转动图(svga后缀名的动图用什么软件观看我在https://svga.io/svga-preview.html网站上看没声音啊,求指点)

大家好,关于svga转动图很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于svga后缀名的动图用什么软件观看我在https://svga.io/svga-preview.html网站上看没声音啊,求指点的知识点,相信应该可以

2026年10月10日 09:30

oracle11g安装和配置(oracle数据库安装在什么地方)

oracle11g安装和配置(oracle数据库安装在什么地方)

本篇文章给大家谈谈oracle11g安装和配置,以及oracle数据库安装在什么地方对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

2026年10月10日 09:10

php安装图文(php页面加入图文编辑框,这是什么技术,请大师指点)

php安装图文(php页面加入图文编辑框,这是什么技术,请大师指点)

大家好,如果您还对php安装图文不太了解,没有关系,今天就由本站为大家分享php安装图文的知识,包括php页面加入图文编辑框,这是什么技术,请大师指点的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

2026年10月10日 08:50

class是什么(class是什么意思啊)

class是什么(class是什么意思啊)

大家好,如果您还对class是什么不太了解,没有关系,今天就由本站为大家分享class是什么的知识,包括class是什么意思啊的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

2026年10月10日 06:20

最近更新

搜索引擎搜索(搜索引擎有哪几种)
2026-10-10 20:30:14 浏览:0
电容器的功能(电容的作用)
2026-10-10 20:00:03 浏览:0
热门文章

标签列表