「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」
redis分布锁有几个实现注意点
- vaule应该是这个客户端的uuid
- 释放的时候应该先判断当前是否当前持有锁的线程再进行释放.
- 另外就是必须有过期时间.
Long startTime = currentTime();
while(true){
if(currentTime > startTime +Time_Out){
return false;
}
if(tryLock(key)){
return true;
}else[
Thread.sleep(1ms);
]
}
public boolean tryLock(key){
boolean result = setNx(key,guoqishijian); // 设置key的过期时间
if(result){ // 如果设置成功,那么就是代表获得锁了
return true;
}
if(checkLock(key)){
getSet(key,time)// 设置当前这个服务应该超时的时间。
}
}
public boolean checkLock(){
Loang time = get(key); // 获取key的超时时间
if(time > currenttime){
return true;
}
}
redis锁的缺点:这对于单点的redis能很好地实现分布式锁,如果redis集群,会出现master宕机的情况。如果master宕机,此时锁key还没有同步到slave节点上,会出现机器B从新的master上获取到了一个重复的锁。
-
zookeeper实现分布式锁原理:
首先知道一下zookeeper的一些东西。他一般有多个节点构成,采用zab协议实现高一致性。它本身有一个持久节点,然后有一些临时节点,这些临时节点是这么来的:一个客户端连接上了zk,就会创建一个临时节点,客户端断开连接这个节点就会取消掉。
临时节点按照时间顺序创建node1,node2.....
通过watcher机制和临时节点机制,来实现分布式锁。临时节点占用普通节点(持久节点),也可以说是在持久节点下创建临时节点,然后看看自己是不是locker下面最小的节点,如果是说明占有了锁,如果不是就对其调用exits方法watch监听最小的节点,但最小的节点消失后,再看看自己是不是最小的节点。
优点:如果客户端宕机了,他会自动断开,锁也就释放了,不需要做什么超时处理。
缺点:也是如果客户端宕机了,他自动断开,但他如果很快的脸上来了,却还是要排队到后面去。同时性能不高,他是对leader进行操作的,我们知道zookeeper会把leader的所有信息同步到所有follwer上。 另外创建节点和销毁节点费时,消耗zk资源。