현재 위치: > 최신 기사 목록> APCU_CAS 기능을 사용하여 캐시 레이스 조건을 피하는 방법

APCU_CAS 기능을 사용하여 캐시 레이스 조건을 피하는 방법

gitbox 2025-05-29

캐시 레이스 조건이란 무엇입니까?

여러 프로세스 나 스레드가 캐시 미스를 읽고 동시에 캐시에 쓰기를 시도하면 여러 프로세스가 동일한 느린 쿼리 또는 복잡한 계산을 동시에 실행하여 리소스 낭비를 초래할 수 있습니다. 이 상황을 캐시 레이스 조건이라고합니다.

예를 들어:

 if (!apcu_exists('my_cache_key')) {
    $data = get_data_from_db(); // 복잡한 쿼리
    apcu_store('my_cache_key', $data);
}
echo apcu_fetch('my_cache_key');

동시성이 높은 환경에서 여러 요청에 따라 캐시가 동시에 존재하지 않으며 데이터베이스 쿼리가 동시에 실행되어 성능 문제가 발생합니다.


APCU_CAS 기능 소개

APCU_CAS 의 전체 이름은 "비교 및 스왑"이며, 캐시 된 값이 예상 값과 동일 여부를 비교하는 데 사용되는 원자 연산이며, 동일하면 새 값으로 대체됩니다. 이 작업은 캐시를 동시에 수정하려는 여러 요청으로 인한 경쟁 문제를 피할 수 있습니다.

기능 프로토 타입 :

 bool apcu_cas(string $key, mixed $old, mixed $new)
  • $ 키 : 캐시 키

  • $ old : 예상 된 오래된 가치

  • $ 새 : 교체 할 새로운 값

  • 진짜 반환은 교체가 성공했음을 의미하고, 거짓은 이전 값이 일치하지 않으며 교체가 실패 함을 의미합니다.


레이스 조건을 피하기 위해 APCU_CAS를 사용하는 방법은 무엇입니까?

"잠금"플래그를 설정하여 MUTEX 액세스 캐시를 구현합니다. 특정 아이디어 :

  1. 캐시를 읽고 존재하는 경우 직접 돌아갑니다.

  2. 캐시가 존재하지 않으면 "잠금"플래그를 설정하여 캐시가 생성되고 있음을 나타냅니다.

  3. "잠금"설정이 실패하여 다른 프로세스가 이미 캐시를 생성하고 대기하거나 다시 시도하고 있음을 나타냅니다.

  4. 설정이 성공한 후에는 느린 쿼리를 실행하여 데이터를 생성하십시오.

  5. 캐시에 데이터를 작성하고 "잠금"플래그를 해제하십시오.

  6. 반환 데이터.


샘플 코드 데모

 function getCacheData() {
    $cacheKey = 'my_cache_key';
    $lockKey = 'my_cache_key_lock';

    // 1. 먼저 캐시를 읽으십시오
    $data = apcu_fetch($cacheKey, $success);
    if ($success) {
        return $data;
    }

    // 2. 통과하려고 노력하십시오apcu_cas잠금을 설정하십시오,여러 요청이 동시에 캐시를 생성하는 것을 방지합니다
    // 先尝试잠금을 설정하십시오标志位为false(초기 상태)
    apcu_add($lockKey, false);

    // 예상 잠금 장치입니다false,변경해보십시오true(잠그다)
    if (!apcu_cas($lockKey, false, true)) {
        // 다른 요청이 잠겨 있음을 나타냅니다,캐시 생성을 기다리십시오
        // 간단 할 수 있습니다sleep또는 루프에서 기다리십시오
        usleep(100000); // 기다리다100밀리 초
        return getCacheData(); // 재귀 적으로 시도하십시오
    }

    // 3. 자물쇠를 얻으십시오,느린 쿼리를 실행하십시오
    $data = get_data_from_db();

    // 4. 캐시를 작성하십시오
    apcu_store($cacheKey, $data);

    // 5. 잠금을 해제하십시오(잠금을 설정하십시오为false)
    apcu_store($lockKey, false);

    return $data;
}

function get_data_from_db() {
    // 느린 쿼리를 시뮬레이션하십시오
    sleep(1);
    return ['time' => time(), 'data' => 'sample'];
}

위의 코드에서 APCU_CAS는 "잠금"의 원자 전환을 보장하고 동시에 느린 쿼리를 실행하라는 여러 요청을 피하고 캐시 경쟁을 피합니다.


요약

  • 캐싱 레이스 ​​조건은 높은 동시성 캐싱 시나리오에서 일반적인 문제입니다.

  • APCU_CAS 는 원자 연산을 구현하기위한 강력한 도구이며 효율적인 잠금 메커니즘을 실현할 수 있습니다.

  • "잠금"메커니즘을 통해 하나의 요청 만 느린 쿼리를 수행하고 캐시를 작성할 수 있으며 다른 요청은 기다리거나 다시 시도 할 수 있습니다.

  • 이 방법은 독립형 환경에서 APCU 캐시에 적합하며 분산 환경에서보다 복잡한 잠금 솔루션을 고려할 수 있습니다.

APCU_CAS 의 사용을 마스터하면 PHP 캐시 메커니즘이보다 강력하고 효율적으로 만들어 캐시 고장으로 인한 성능 병목 현상을 크게 피할 수 있습니다.


<code> <? php 함수 getCachedata () {$ cachekey = 'my_cache_key'; $ lockkey = 'my_cache_key_lock';
 $data = apcu_fetch($cacheKey, $success);
if ($success) {
    return $data;
}

apcu_add($lockKey, false);

if (!apcu_cas($lockKey, false, true)) {
    usleep(100000);
    return getCacheData();
}

$data = get_data_from_db();

apcu_store($cacheKey, $data);

apcu_store($lockKey, false);

return $data;

}

함수 get_data_from_db () {
수면 (1);
return [ 'time'=> time (), 'data'=> 'sample'];
}
?>
</코드>