Redis 分布式锁

如果追求高可用性(AP) 就采用redis

如果追求高一致性(CP) 就采用zookeeper

加锁方式:set lockKey uniqueId NX PX expireTime

  • lockKey可以根据业务自己定义(如订单)
  • uniqueId是为了不解错锁(uniqueId可以是session Id 或者线程Id等)

怎么会解错锁?举个小案例吧

S1 获得Lock,ttl时间5s,实际执行了7s

S2 获得Lock,ttl时间5s,实际执行了4s

如果没有uniqueId S1在第7s的时候解锁,或解了S2的锁

  • NX代表当前不存在锁的时候才能加锁成功
  • PX 毫秒过期时间,如果是秒就用ES

解锁方式:通过lua脚本实现原子操作,先进行uniqueId对比操作,如果相同,则执行del解锁操作

if redis.call("GET",KEYS[1]) == ARGV[1]

then

return redis.call("DEL",KEYS[1])

else

return 0

end

续期:当分布式锁到达了超时时间,但是业务并没有完成,则将对锁进行续期

  • S1 获得Lock,ttl时间5s,实际执行了7s,如果没有续期那么S1后2秒就没有锁

续期的两种方式:

  • 开启一个后台守护线程,每隔3秒对key设置ttl时间5S进行续期,当主线程执行完操作之后,对key进行解锁,那么守护进行也随之消亡
  • 采用异步任务,获得锁后,把所有锁的线程放到一个Map里,然后每隔几秒进行轮询,如果客户端还持有锁(即Map中还存在),就延长ttl时间

RedLock算法对应的场景 主节点挂掉后,lockkey还未同步到从节点,导致从节点上没有lockkey(发生概率很小,面试官喜欢在AP模型里解决CP模型的问题)

  • 对3个完全独立的redis主服务器一次获得锁(一般要基数个,为了少数服从多数)
  • 如图请求时间4000-1000=3s小于TTL时间5s,并且至少有半数(大于2个)获得锁,才算真正获得锁

缺点(已废弃,不常用,因此只学习算法思想)

  • 复杂度高,需要设计一些算法去实现
  • 不可靠,如果redis主服务器宕机,会影响到锁的使用(即少数服从多数会受影响)
  • 性能瓶颈,需要访问多个redis实例
  • 另外最要命的是还需要求所有redis主服务器的系统时间一致性
相关推荐
银发控、3 小时前
MySQL联合索引
数据库·mysql
予枫的编程笔记3 小时前
【MySQL修炼篇】从踩坑到精通:事务隔离级别的3大异常(脏读/幻读/不可重复读)解决方案
数据库·mysql·后端开发·数据库事务·事务隔离级别·rr级别·脏读幻读不可重复读
睡美人的小仙女1273 小时前
Threejs加载环境贴图报错Bad File Format: bad initial token
开发语言·javascript·redis
上海锟联科技3 小时前
DAS 系统 250MSPS 是否足够?——来自上海锟联科技的专业解析
分布式·科技·分布式光纤传感·光频域反射·das
徐同保4 小时前
解决 Vue 3 项目 TypeScript 编译错误:@types/lodash 类型定义不兼容
redis·网络协议·https
一起养小猫4 小时前
Flutter for OpenHarmony 实战:记账应用数据统计与可视化
开发语言·jvm·数据库·flutter·信息可视化·harmonyos
世界尽头与你4 小时前
(修复方案)CVE-2023-22047: Oracle PeopleSoft Enterprise PeopleTools 未授权访问漏洞
数据库·安全·oracle·渗透测试
韩立学长4 小时前
【开题答辩实录分享】以《智能大学宿舍管理系统的设计与实现》为例进行选题答辩实录分享
数据库·spring boot·后端
Henry Zhu1234 小时前
数据库(五):反规范化
数据库
Mr_Xuhhh5 小时前
MySQL函数详解:日期、字符串、数学及其他常用函数
java·数据库·sql