다음 칼럼에서는 Redis Tutorial에서 Redis의 SETNX를 사용하여 잠금 메커니즘을 구현하는 방법을 소개합니다. 도움이 필요한 친구들에게 도움이 되기를 바랍니다.
setNX는 set이 존재하지 않는 경우의 약어입니다. 즉, 존재하지 않는 경우에만 설정됩니다. 설정에 성공하면 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/ setNX는 성공했지만 Expire는 실패하는 것을 방지하기 위해 Exec을 사용하여 요청의 원자성을 보장해야 합니다. 여기에는 여전히 문제가 있습니다. 여러 요청이 도착하면 하나의 요청의 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); }
위 내용은 Redis의 SETNX를 올바르게 사용하여 잠금 메커니즘을 구현하는 방법을 가르칩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!