写点什么

redis 实现分布式锁(二)

作者:zarmnosaj
  • 2022-10-17
    四川
  • 本文字数:617 字

    阅读完需:约 1 分钟

使用 Lua 脚本

简单说一下 Lua 脚本的特点:首先 Lua 是一种轻量的脚本语言,用标准语言编写,并于源代码形式开放,非常适合嵌入别的程序里、Lua 也提供了非常易于使用的扩展接口和机制、支持面向过程编程和函数式编程、自动内存管理等。


在全面提到,使用命令 SETNX + EXPIRE 实现分布式锁的方案中,是由于两个操作不是原子操作,会导致分布式锁无法实现的原因。


要保证原子性,还有一种方式可以实现,就是使用 Lua 脚本,

SET 的扩展命令(SET EX PX NX)

除了使用 Lua 脚本保证 SETNX + EXPIRE 两条指令的原子性,还可以使用 Redis 的 SET 指令扩展参数:SET key value EX|PX NX|XX,这也是具有原子性的。


参数解释:


  1. 其中的 EX,指的是 key 的过期时间

  2. PX 和 EX 一样,指的过期时间,只是单位不一样,PX 是毫秒,EX 是秒。

  3. NX 表示在指定 key 不存在时,才能成功执行命令

  4. XX 和 NX 相反,是指定 key 存在时,才会成功执行命令,不然会失败

SET EX|PX NX|XX + 唯一 value 值(UUID)

SET 的扩展命令(SET EX PX NX)方式的缺点:


  1. 存在一种情况:指定的 key 已经过期了,但是线程还没执行完逻辑,到期锁就自动释放,此时别的锁开始争抢锁并执行逻辑,这会使程序混乱。

  2. 在设置 key 时,没有规定只能设置的线程去释放,只要指定的 key 值,其他线程可以直接对 key 进行删除。


解决方案:设置 key 时,线程生成一个随即不重复的数,比如生成 UUID,然后临时保存起来。删除 key 时,校验 key 中保存的 value 是否是当前线程临时保存的 UUID,如果不是,则无法删除锁,只要是的情况下才能删除 key 释放锁。

发布于: 刚刚阅读数: 3
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020-02-06 加入

成都后端混子

评论

发布
暂无评论
redis实现分布式锁(二)_10月月更_zarmnosaj_InfoQ写作社区