目录
为什么需要分布式锁?
分布式项目,每个项目独立。需要锁独立于每个服务之外,而不是在服务里面。
一、数据库
- 利用主键冲突控制一次只有一个线程能获取锁,非阻塞、不可重入、单点、失效时间等。
二、Zookeeper分布式锁
zk通过临时节点,解决了死锁的问题,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉,其他客户端自动获取锁,临时顺序节点解决惊群效应(在多进程/多线程等待同一资源时,也会出现惊群。即当某一资源可用时,多个进程/线程会惊醒,竞争资源。这就是操作系统中的惊群)。
三、Redis分布式锁
settnx,单线程处理网络请求,不需要考虑并发安全性,所有服务节点设置相同的key,返回0,则锁获取失败。
setnx问题:
- 早期版本没有超时参数,需要单独设置,存在死锁问题(中途宕机)。
- 后期版本提供加锁与设置时间原子操作,但是存在任务超时,锁自动释放,导致并发问题,加锁与释放锁不是同一线程问题。
删除锁:判断线程唯一标识,再删除。
可重入性及锁续期没有实现,通过Redisson解决(类似AQS的实现)
redlock:redis通过哨兵模式保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况(redis同步可能数据丢失)。redlock从多个节点申请锁,当一半以上节点获取成功,锁才算获取成功,Redisson有相应的实现。