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 无法处理其他请求。

相关推荐
隐擎fox1 小时前
高性能网络爬虫架构设计:基于 Python 的长连接复用与分布式会话池调度实践
分布式·python·网络协议·tcp/ip·高并发·网络爬虫、
momo061174 小时前
Redis新手入门 -- 学习笔记
redis·后端
闲云自留地7 小时前
云平台存储管理员:Cinder 创建挂载卷 + Swift 分布式存储原理
分布式·wpf·swift
橙子圆12311 小时前
RabbitMQ知识1
分布式·rabbitmq
写后端的胖头鱼12 小时前
【高频面试题】spring事物失效场景(带原理 + 代码示例)
java·后端·spring·事务·事物失效
clz131452112 小时前
风险特征系统 EPC 子系统:基于 Kafka 数据源与数据集配置的 Flink 指标清洗加工
分布式·flink·kafka
吃饱了得干活12 小时前
Redisson 进阶实战:看门狗机制与分布式锁完全指南
java·redis·后端
海上小飞龙13 小时前
分布式和微服务,一次讲清
分布式·微服务·架构
我是苏苏14 小时前
Redis开发09:Windows系统下主从复制的配置教程
数据库·redis·缓存
(Charon)14 小时前
【Kafka】消息队列学习(二):Topic、Partition与Offset,消息到底存在哪里
分布式·学习·kafka