使用Redis锁可能出现的问题
分布式锁
分布式锁常规情况下都是使用redis来实现。很早以前,使用SETNX加过期命令进行设置,无法保证原子性。但随着时代的发展,redis已经支持一条指令(set指令)实现setnx加过期时间。
什么是线程不安全?
线程不安全指的是多个线程操作一个资源,期望值和获取到的数据不一致。
可能存在的问题
没有一种解决方案是银弹
- 在使用分布式锁的情况下,需要考虑如果一个线程获取到锁之后,如果业务处理产生了耗时操作,或者调用第三方接口超时,导致当前线程拿到的锁过期,这个时候,其他线程就会获取锁,然后进入业务处理方法,此时可能会出现线程不安全的情况。
- 解决方案:针对超时导致锁过期,其他线程进入的情况,可根据业务,设置一个合理的过期时间。或者自动续期。采用Redisson就可以实现自动续期
- 针对第一种情况,还存在如果第一个线程耗时,锁以及过期,线程2拿到了锁,但是这个时候,线程1执行完成了。这个时候,线程1就释放了线程2的锁
- 解决方案:给锁一个唯一标识,只有锁的唯一标识和当前线程设置的唯一标识对应上了才能删除。但是删除的时候需要先根据key获取到uuid。无法保证原子性。所以还得结合lua脚本保证原子性。
- 大量请求打击到redis服务上,导致redis服务崩溃。
- 解决方案:redis进行高可用配置,配置主从以及哨兵机制。但是这种解决方案也会存在锁失效的情况,就是如果主节点挂了,但是锁的状态还没同步到其他节点,就会出现其他线程可以获取锁的情况。redis的作者提示了redLock(红锁)但是这种解决方案似乎是存在问题,对于时钟问题比较敏感。如果要防止上面的问题,最终还是需要有一个兜底的方案,保证锁出问题的情况下,不会对数据的结果产生太大的问题。
谨记:一个分布式锁,在极端情况下,不一定是安全的。如果对数据很敏感,一定要有兜底的策略。当然,现在似乎人肉解决数据不一致的情况是比较常见的。
Redis常用操作类库Redisson
如果非必须,建议使用Redisson进行开发,多人开发的肯定比自己造轮子的强
但是也要理解原理
一万年太久,只争朝夕!
本文作者:暮雪超霸
本文链接:https://www.cnblogs.com/chaoba/p/16039296.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!