Setting原来Redis锁设置过期时间也有秘诀(redis锁 过期时间)
锁是广泛应用于系统设计中的一种功能,它可以帮助我们完成任务安全、一致性和原子性。Redis作为最流行的数据库,使用它来完成一些高可用性的任务时,对它的锁也能秒杀各种其他任务调度工具。但是,在使用Redis锁的过程中,有一个特别值得注意的地方:设置Redis锁的过期时间,如果不设置正确的过期时间,就容易引起死锁现象甚至使系统瘫痪。
先说一下为什么要设置合理的Redis锁过期时间。在Redis客户端去请求加锁之后,正常情况下会设置expire,作为临时有效期,一旦该操作执行完毕,本次锁就会自动失效,不会造成死锁情况。如果某些原因导致Redis客户端无法正常请求unlock或者key被意外修改,那么这把锁便要等待一段时间过期,而不会影响后续的任务执行。
那么如何设置Redis锁的过期时间才算合理呢?主要有几方面的原则:
1. 首先就是确定完成任务的具体时间,明确任务的剩余时间,然后在比这个小一点的范围内设置Redis锁的expire即可。
2. 同样,另外一个要考虑的是锁争夺多个客户端,在短时间内完成任务,根据在数据中读取和处理的时间间隔,再设置一个合理的expire时间。
3. 如果要设置一个长期保持的锁,比如唤醒定时任务,则需要根据定时任务的周期,设置加锁key的expire,以保证锁保持有效。
下面是设置Redis锁的expire时间的一段示例代码:
“`java
String key = “lockKey”;
//获取当前时间戳
long currentTime = System.currentTimeMillis();
//设置锁的过期时间
long expireTime = currentTime + 10 * 1000 ; //10s
if(jedis.setnx(key, String.valueOf(currentTime)) == 0)
{
//已存在锁
String oldTime = jedis.get(key);
if(currentTime – Long.valueOf(oldTime) > 10 * 1000) {
//此处如果多次setnx,但只会有一次setnx成功
if (jedis.getSet(key, String.valueOf(currentTime)) == oldTime) {
jedis.expire(key, 10); //设置成功,为锁设置10s的过期时间
}
}
}
else {
jedis.expire(key,10); //设置成功,为锁设置10s的过期时间
}
在使用Redis锁设置过期时间的时候,要根据不同的使用场景,合理设置超时时间,从而减少死锁的几率。只有当锁过期时间到期,Redis客户端有机会重新请求加锁,这样才能保证没有任务失效,从而达到大家期待的高可用目标。