Redis原子操作
Redis命令的原子操作
redis虽然是单线程,但是一个客户端发送的一组命令却不是原子操作。
redis自带的原子操作命令有incr {key}、decr {key}等,但是更为复杂的命令,比如先获取值,然后乘以2,最后置为新值这三步操作,有可能中间会有其他客户端的命令插入导致值已经变化,出现并发问题。
可以利用LUA脚本解决这个问题,比如常见的判断分布式锁是否为当前客户端的锁,判断成功才进行释放操作。
if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end
利用Redis实现的分布式锁
JDK自带的锁只锁协调一个实例中的临界区并发调用,但是分布式锁可以跨越实例上的限制。利用Redis天生单线程执行命令的特性,可以很简单的实现分布式锁。
首先获取一个随机的字符串作为锁的值,并利用原子命令set {key} {val} nx ex {time}
同时设置值和过期时间即可。需要释放锁的时候,利用前文中的LUA脚本完成锁的释放操作。
LUA脚本中判断值是为了避免这样一种情况,线程A执行时卡顿了,导致A加的锁过期自然解锁,此时线程B重新加锁后,线程A继续执行,把线程B的锁给释放掉了。通过加锁时赋予一个独一的随机值,可以避免这种情况的发生。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?