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

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

一、Redis事务的局限性

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

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

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

但 Redis 事务是 "批量执行,无中间判断" 的 ------GETDEL 会被强制一起执行,无法根据 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 无法处理其他请求。

相关推荐
Albert Edison8 小时前
【Redis】Centos7.9 安装 Redis 5 教程
数据库·redis·缓存
ha_lydms9 小时前
AnalyticDB分区、分布键性能优化
android·大数据·分布式·性能优化·分布式计算·分区·analyticdb
Steadfast_GG9 小时前
Redis中的通用命令
redis·缓存
小二·9 小时前
Redis 内存溢出(OOM)排查与恢复实战
数据库·redis·bootstrap
pqk6V6Vep9 小时前
Redis 分布式锁进阶第一篇讲解
数据库·redis·分布式
giaz14n9X9 小时前
Redis 分布式锁进阶第六十一篇
数据库·redis·分布式
洛水水11 小时前
消息队列与Kafka详解
分布式·kafka
鸿乃江边鸟12 小时前
Spark中怎么做Spark canonicalize归一化
大数据·分布式·spark
JAVA面经实录91712 小时前
Redis 知识体系(完整版)
java·redis·nosql数据库·nosql
SLD_Allen12 小时前
Kafka分区与消费者的关系kafka分区和消费者线程的关系
分布式·kafka