分布式锁(Redis/ZooKeeper/MySQL)
2020-10-10 11:19:50 6 举报
AI智能生成
分布式锁
作者其他创作
大纲/内容
特点
互斥性
在任意时刻,只有一个客户端能持有锁
安全性
锁只能被持有该锁的客户端删除,不能由其它客户端删除
高可用
当部分节点down机时,客户端仍然能够获取锁和释放锁
防死锁
防止客户端持有锁期间崩溃没有释放锁,设置过期时间ttl
基于Redis
注意问题
加锁命令和超时时间要同时设置【保证原子性】
value要具有唯一性(可用UUID)【防止误解锁】
使用定时任务定期检查锁的状态【超时续命】
每次检查锁还在的话,将锁的超时时间重制
每次检查锁还在的话,将锁的超时时间重制
加锁实现
SET key value [EX seconds] [PX milliseconds] [NX|XX]
stringRedisTemplate.opsForValue().setIfAbsent(String key,String value,long timeout,TimeUnit unit)
jedis.set(String key, String value, String nxxx, String expx, long time);
【存在风险】如果是主从架构,主节点加锁后挂了,数据还没同步到从节点,
此时slave升级为master,如果再有线程加锁会出现多个客户端持有锁的情况
此时slave升级为master,如果再有线程加锁会出现多个客户端持有锁的情况
Redisson
自带锁续命功能(每隔超时时间的1/3检测一次)
基于RedLock算法,解决单节点分布式锁在故障迁移时产生的安全问题
基于Zookeeper
实现
临时+有序节点
临时节点:避免死锁
有序节点:避免羊群效应
比如在/lock目录下,创建临时有序节点,创建成功后比较该目录下的所有节点,判断自己的序号
是不是最小的,如果是则获取分布式锁成功,否则对当前节点序号的前一个节点添加监听就ok了
是不是最小的,如果是则获取分布式锁成功,否则对当前节点序号的前一个节点添加监听就ok了
特点
相比于redis来说更加健壮,且简单易实现,不过redis性能更高
性能损耗小,没有获取锁时只需添加监听,不需要一直轮询
数据库
基于表记录
直接在数据库中创建一张表,表里包含方法名等字段,并且在方法名字段上面创建唯一索引
使用时将方法名作为参数在表中插入一条记录,插入成功即获取锁,释放锁时删除记录即可
使用时将方法名作为参数在表中插入一条记录,插入成功即获取锁,释放锁时删除记录即可
缺点
没有失效时间,需要靠定时任务去跑
获取锁失败会报错,建议使用队列排队
实现可重入锁需要添加字段累加
基于乐观锁
基于悲观锁
关于作者
我的博客 👉
GitHub 导航 👉
ProcessOn 主页 👉
微信扫一扫,点击加号 👉
更多精彩的文章等待你的发掘,欢迎你的关注
0 条评论
下一页