redis分布式锁为什么采用Lua脚本实现。而不是事务

Redis 分布式锁使用 Lua 脚本而非事务,核心原因是 Lua 脚本能保证分布式锁操作的 "原子性" 和 "灵活性",而 Redis 事务在某些场景下无法满足分布式锁的核心需求。

一、Redis事务的局限性

redis分布式锁的核心是先判断自己是否持有锁,然后在进行释放。

用 Redis 事务实现时,需要分两步:

java 复制代码
MULTI
GET lock:key  # 1. 判断锁是否归属自己
DEL lock:key  # 2. 释放锁(仅当归属自己时)
EXEC

但 Redis 事务是 "批量执行,无中间判断" 的 ------GET 和 DEL 会被强制一起执行,无法根据 GET 的结果决定是否执行 DEL。即使锁已被其他客户端抢占,DEL 仍会执行,导致 "误释放他人锁" 的严重问题。

二、lua脚本的优势

Lua脚本能够保障redis服务端原子性的执行一系列的命令,且不会被其它客户端打断,确保条件判断和后续操作的原子性

如释放锁的Lua脚本:

java 复制代码
-- 释放锁:仅当锁的value是自己的标识时才删除
if redis.call("GET", KEYS[1]) == ARGV[1] then
    return redis.call("DEL", KEYS[1])  -- 释放锁
else
    return 0  -- 不释放他人的锁
end

这段脚本会原子性地完成 "判断锁归属" 和 "释放锁" 两个操作,避免了事务中 "判断和执行分离" 的问题。

同时Lua可以提高分布式锁的性能,

分布式锁的操作(如 "判断 + 释放")若用多条命令分步执行,需要多次网络往返(客户端→Redis→客户端)。

用 Lua 脚本可以将多步操作合并为一次网络请求,减少网络延迟,尤其在分布式环境中能显著提升性能

补充:为什么Lua脚本是单线程的?

Redis 是单线程处理命令的,

整个脚本会被当作一个不可分割的整体,在执行过程中不会被其他客户端的命令打断,直到脚本完全执行完毕,

同时Redis 明确禁止在 Lua 脚本中执行会阻塞主线程的操作 (如BRPOP等阻塞命令、长时间循环)。这确保了 Lua 脚本的执行时间是可控的,不会因为脚本执行过久导致 Redis 无法处理其他请求。

相关推荐
ly76895 小时前
Redis 分布式锁的边界条件:Redlock 争议、锁续期与客户端崩溃后的互斥失效
数据库·redis·分布式·分布式锁·watchdog·redlock
灯澜忆梦7 小时前
【minio】#5 | MinIO 分布式部署 + HTTPS 部署
分布式·网络协议·https·对象存储·minio
ShineWinsu8 小时前
对于Redis:RDB持久化的解析
linux·数据库·redis·缓存·面试·持久化·rdb
谢亮_vipxieliang17 小时前
Spring Cloud 服务治理入门:注册发现、配置中心、网关限流、熔断降级与分布式一致性方案
分布式·spring·spring cloud
hweiyu0020 小时前
Redis命令:HTTL
redis·缓存
樱花落木兰1 天前
分布式登录实战:Session 会话共享改造,Redis 存储用户登录状态
java·javascript·数据库·redis·分布式·缓存
ShineWinsu1 天前
对于Redis:Steam、Geospatial、Hyperloglog、Bitmap、Bitfield类型的解析
数据库·c++·redis·分布式·缓存·面试·zset
海绵宝宝转agent1 天前
基于Redis ZSet+AOP+注解实现限流注解算法
数据库·redis·算法
imDwAaY1 天前
Redis 也能做消息队列?从 Stream 的存储讲到消费确认
数据库·redis·缓存
imDwAaY1 天前
Redis 哈希表如何边扩容边服务?讲透渐进式 Rehash
redis·哈希算法·散列表