红锁定实现多机分布式锁的途径(多机redis分布式锁)
在分布式系统中,从系统可靠性的角度看,经常会有共享资源被多个机器请求等乱写情况发生,所以必须要求资源在特定时间只能一个进程进行访问,如果有第二个进程想要访问,就需要等待上一个进程释放资源,这就要求系统拥有一个机制来控制和协调进程或机器对该资源的访问,就需要实现多机分布式锁,这种被普遍使用的技术就是所谓的”红锁定”(RedLock)。
红锁定是一种基于Redis分布式锁的实现方式,它以Redis实例作为背景,在整个系统中实现多个服务器之间的共享资源加锁实现,它既可以保证多个系统有序并发访问资源,又可以保证在线程异常终止时,能够恢复进程之间的锁定关系。
红锁定的实现结构大致如下:
1. 在多个Redis实例中设定一个特定的Key:Value对,如 set “key”:“value” NX EX 10,它的含义为key不存在时,将value设置成key的值,有效期10秒;
2. 所有的服务器上要实现相同的功能,要向Redis发送一个检索命令,如检索key的值;
3. 如果 key 的值为“value”,那么表示资源正在被锁定,其它服务器可以在这里等待,或者可以断开连接;
4. 如果 key 的值为null,那么表示资源空闲,这时服务器可以尝试设置 key 并获取资源;
5. 如果设置成功,服务器就可以获取资源,并在操作完成之前以及操作失败的处理中,都要注意清除加锁的资源;
6. 等待超时时间(wtTimeout)到达,若还未获取到所需的资源,则中断等待,释放连接。
红锁定的实现代码如下:
public class RedLock {
private static final int DEFAULT_WT_TIMEOUT = 30;
public boolean lock(String key, long wtTimeout) {
if (wtTimeout
wtTimeout = DEFAULT_WT_TIMEOUT;
}
long start = System.currentTimeMillis();
while (true) {
// 尝试获取锁
boolean result = tryGetLock(key);
if (result) {
return true;
}
long now = System.currentTimeMillis();
long elapsed = now – start;
if (elapsed >= wtTimeout) {
break;
}
}
return false;
}
// 尝试获取锁
private boolean tryGetLock(String key) {
String value = UUID.randomUUID().toString();
if (!getRedis().setnx(key, value)) {
return false;
}
return true ;
}
}
红锁定是一种有效的多机分布式锁的实现方式,它的特点就是既可以保证多个服务器有序并发访问资源,又可以保证在线程异常终止时,能够恢复进程之间的锁定关系,达到系统共享资源安全,并发并发访问高效有序的目的,获得了众多分布式系统的应用。