2022年01月14日整理发布:教你正确地使用Redis的SETNX实现锁机制

导读 我将向您解释如何教您如何使用Redis的SETNX来正确实现锁机制。相信朋友们也应该密切关注这个话题。现在,我将教您如何使用Redis的SETNX正确...

我将向您解释如何教您如何使用Redis的SETNX来正确实现锁机制。相信朋友们也应该密切关注这个话题。现在,我将教您如何使用Redis的SETNX正确实现锁机制。边肖还收集了相关信息,教你如何使用Redis的SETNX正确实现锁机制。我希望你看到后会喜欢。

下面,Redis教程专栏将为大家介绍如何正确使用Redis的SETNX实现锁定机制,希望对有需要的朋友有所帮助!

SetNX是set if not exists的缩写,即只在不存在时设置,设置成功时返回1,设置失败时返回0。它可以用来达到锁定的效果,但是很多人在使用的过程中没有考虑到它就出现了一些问题。

例如,查询数据库的接口由于请求量大而添加了缓存,并设置缓存在过期后刷新。当并发量大,缓存过期时,大量并发请求会直接查询数据库,造成雪崩。如果锁定机制仅用于控制一个更新缓存的请求,则可以避免雪崩问题。以下是很多人下意识想到的锁定方法。

$rs=$redis-setNX($key,$ value);

if ($rs)

//处理更新缓存逻辑

//.

//删除锁

$ redis-del($ key);

}通过setNX获取锁。如果成功,请更新缓存并删除锁。其实这里有一个很严重的问题:如果更新时因为某种原因意外退出了缓存,锁不会被删除,会一直存在,这样缓存就不能再更新了。为了解决这个问题,有些人可能会考虑为锁设置一个过期时间,如下所示

$ redis-multi;

$redis-setNX($key,$ value);

$redis-expire($key,$ TTL);

$ redis-exec;由于setNX没有设置过期时间的功能,所以需要使用Expire来设置,需要Multi/Exec来保证请求的原子性,以防止setNX成功过期却失败。还有一个问题:当多个请求到达时,虽然只有一个请求的setNX可以成功,但任何一个请求的Expire都可以成功,这意味着即使无法获得锁,也可以刷新过期时间,使锁始终有效,但上述问题无法解决。显然,setNX无法满足需求。Redis从2.6.12开始,SET就涵盖了SETEX的功能,而SET本身也包含了设置到期时间的功能,所以使用SET可以解决上述问题。

$rs=$redis-set($key,$value,array('nx ',' ex '=$ TTL));

if ($rs)

//处理更新缓存逻辑

//.

//删除锁

$ redis-del($ key);

}其实现阶段还是有问题的。如果请求更新缓存的时间比锁的有效期长,则在缓存更新过程中锁将无效。此时,另一个请求将获得锁。但是,如果前一个请求在缓存更新后直接删除锁,其他请求创建的锁将被错误删除。因此,为了避免这个问题,需要在创建锁时引入一个随机值,并在删除锁时进行判断。

$rs=$redis-set($key,$random,array('nx ',' ex '=$ TTL));

if ($rs)

//处理更新缓存逻辑

//.

//首先判断随机数相同,然后删除锁。

if($ redis-get($ key)==$ random){ 0

$ redis-del($ key);

}

}以上就是教你如何正确使用Redis的SETNX实现锁定机制的细节!

来源:php中文网站

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

猜你喜欢

最新文章