避免掉入 SETNX(SET if Not eXists) 陷阱的最好方法就是永远不要使用它:
setnx lock “lock”
expire lock 100
del lock
场景:某个查询数据库的接口,因为调用量比较大,所以加了缓存,并设定缓存过期后刷新.
问题是当并发量比较大的时候,如果没有锁机制,那么缓存过期的瞬间,大量并发请求会穿透缓存直接查询数据库,造成雪崩效应. 如果有锁机制,那么就可以控制只有一个请求去更新缓存,其它的请求视情况要么等待,要么使用过期的缓存.
$key = ‘cache_update_lock’; //锁
$random = md5( uniqid(getmypid().’_’.mt_rand().’_’, true) ); //随机值
$ttl = 10; //nx表示not exists,ex表示expire,ttl表示time to live,单位是秒.
if( $redis->set($key, $random, [‘nx’, ‘ex’ => $ttl]) ) {
$cache->update(); //加锁后执行业务逻辑,这里是更新缓存
//加入随机值判断是为了避免删除到其他操作的锁
if($redis->get($key) == $random) {
$redis->del($key);
}
}
没有回复内容