分布式锁
数据库
唯一索引、排他性
建表核心为业务防重复ID、锁持有者ID
redis
redis单机是CP
单机不满足高可用
可以自己实现单机版redis分布式锁,要考虑锁的释放、死锁问题、原子性问题,存在缺点
Redisson有看门狗机制,还有3段lua脚本保证原子性
public class WatchDogDemo
{
public static final String LOCKKEY = "AAA";
private static Config config;
private static Redisson redisson;
static {
config = new Config();
config.useSingleServer().setAddress("redis://"+"192.168.111.147"+":6379").setDatabase(0);
redisson = (Redisson)Redisson.create(config);
}
public static void main(String[] args)
{
RLock redissonLock = redisson.getLock(LOCKKEY);
redissonLock.lock();
try
{
System.out.println("1111");
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(25); } catch (InterruptedException e) { e.printStackTrace(); }
}catch (Exception e){
e.printStackTrace();
}finally {
redissonLock.unlock();
}
System.out.println(Thread.currentThread().getName() + " main ------ ends.");
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
redisson.shutdown();
}
}
redis集群(主从模式)是AP
存在风险:主节点的数据还没来得及同步给从节点就挂了
多主模式
N=2X+1个主节点,半数以上拿到锁才行
redlock==>RedissonRedLock
public class RedLockController {
public static final String CACHE_KEY_REDLOCK = "ZZYY_REDLOCK";
@Autowired
RedissonClient redissonClient1;
@Autowired
RedissonClient redissonClient2;
@Autowired
RedissonClient redissonClient3;
@GetMapping(value = "/redlock")
public void getlock() {
//CACHE_KEY_REDLOCK为redis 分布式锁的key
RLock lock1 = redissonClient1.getLock(CACHE_KEY_REDLOCK);
RLock lock2 = redissonClient2.getLock(CACHE_KEY_REDLOCK);
RLock lock3 = redissonClient3.getLock(CACHE_KEY_REDLOCK);
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
boolean isLock;
try {
//waitTime 锁的等待时间处理,正常情况下 等5s
//leaseTime就是redis key的过期时间,正常情况下等5分钟。
isLock = redLock.tryLock(5, 300, TimeUnit.SECONDS);
log.info("线程{},是否拿到锁:{} ",Thread.currentThread().getName(),isLock);
if (isLock) {
//TODO if get lock success, do something;
//暂停20秒钟线程
try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); }
}
} catch (Exception e) {
log.error("redlock exception ",e);
} finally {
// 无论如何, 最后都要解锁
redLock.unlock();
System.out.println(Thread.currentThread().getName()+"\t"+"redLock.unlock()");
}
}
}
zookeeper
zookeeper集群是CP,为了保证一致性,牺牲了一定的可用性。
客户端注册给某一台follower,这台follower再同步给leader,leader再同步给其他follower,整个过程都完成,客户端才能收到注册成功。
leader要是挂了,整个选举期间,zk不可用。
原理是创建临时顺序节点、最靠前的获得锁。
Zookeeper第三方客户端curator中已经实现了基于Zookeeper的分布式锁。
版权声明:本文所有权归作者! 商业用途转载请联系作者授权! 非商业用途转载,请标明本文链接及出处!
赞成、反驳、不解的小伙伴,欢迎一起交流!

浙公网安备 33010602011771号