Redis作为一种使用场景广泛、响应快、性能高的内存数据库锁服务,在各种网站应用中有着广泛的应用。 锁本身是一种保护资源免受多线程并发环境带来损失的手段,然而往往会有一些意外的情况,导致Redis锁没能有效保护并抵御多线程并发的攻击,从而引发一些储备性的问题比如超卖,下面就对Redis锁没有能够有效保护的原因作一个详细的分析,并找出一些有效的解决方案。
首先Redis锁没能有效保护的原因之一是Redis宕机所导致的,目前Redis是基于内存运行的,当Redis宕机后,该key就会被删除,客户端并不会收到任何响应,从而导致Redis锁没有有效保护,而且此种情况普遍存在。
另外,Redis使用Lua得脚本,原子脚本的操作的decrby之类的脚本,在进行创建锁或者释放锁操作时,由于服务器压力大,可能会导致延时返回,服务器一直不返回,也会导致这个key锁无法被删除,故而产生不可控的影响。
此外,Redis运行释放锁命令时,有时也会出现报错,从而导致解锁失败,也是无论如何都无法有效保护的一种情况。
要解决上面出现的问题,首先大家可以通过增加数据库容量来减少压力,一旦服务器出现延时或错误的情况,也可以重新尝试再次执行解锁操作,若依然失败,则可以通过设置定时任务来多次执行这个解锁操作,比如:
“`js
// 30秒后重试5次
var count = 5;
var interval = 30;
setInterval(function(){
if(count>0){
// 重新调用解锁接口
count–;
} else {
// 停止定时器
}
},interval);
另外,使用Redis集群,能够极大提高Redis存取性能,尽量把Redis中的锁都存储到某一个特定的服务器上,这样再有宕机的情况发生时,也能够确保该Key锁不会丢失,从而保证释放和获取锁操作的可靠性。
为了解决Redis锁没有有效保护的问题,客户端也可以提供监视机制,在客户端可以定义一个自定义的超时时间,当过期的时候,会相应的释放掉该锁,从而保证了锁在合理的时间里不会因为客户端宕机而一直处于锁定状态,从而提高了整体系统的性能。
如果要有效保护Redis锁,要实现延时解锁、可以收到响应、减少报错等功能,那么应该考虑缩小存取压力,使用Redis集群,增加数据库的容量,以及添加必要的超时处理等方案,从而有效保护Redis锁,避免出现不可控的影响。