PHP의 캐시 전략에서 APCU_ENTRY () 함수는 캐시 읽기 및 쓰기 작업을 단순화하는 데 널리 사용됩니다. 캐시가 존재하지 않을 때 자동으로 생성하고 데이터를 저장하는 콜백 기능을 제공하여 코드를 더 간결하게 만듭니다. 그러나 부적절하게 사용하면 "캐시 침투"문제가 발생하여 시스템에 추가 부담이 발생할 수 있습니다.
이 기사는 apcu_entry ()를 사용하는 과정에서 캐시 침투를 효과적으로 피하는 방법을 살펴 봅니다.
캐시 침투는 캐시 시스템 쿼리가 누락되고 백엔드 데이터베이스가 데이터를 찾을 수없는 상황을 나타냅니다. 공격자 또는 크롤러는 존재하지 않는 데이터를 지속적으로 요청하고 캐시 계층을 우회하며 데이터베이스에 직접 액세스하여 데이터베이스 압력이 갑자기 증가 할 수 있습니다.
APCU_ENTRY () 의 맥락에서, 각각의 놓친 키에서 데이터베이스 쿼리가 수행되면 캐시에 녹색 채널을 제공하는 것과 같습니다.
$value = apcu_entry("user_123", function() {
// 데이터베이스에서 데이터를 가져옵니다
return fetch_user_from_db(123);
});
이 코드는 논리적으로 간결합니다. 키가 존재하지 않으면 콜백 함수가 자동으로 호출되고 반환 결과가 캐시에 저장됩니다. 그러나 fetch_user_from_db ()를 반환하면 NULL (예 : 사용자가 존재하지 않음)을 반환하면 NULL 도 캐시됩니까? 기본값은 예입니다. 문제는 다음과 같습니다.
NULL 이 캐시되지 않으면 데이터베이스는 모든 요청이 트리거됩니다.
NULL 이 캐시 된 경우 캐시 시간과 "데이터 확인"과 "데이터 만료"를 구별하는 방법에주의를 기울여야합니다.
데이터베이스에서 데이터를 찾을 수없는 경우 특수 플래그 값이 반환되고 짧은 만료 시간이 설정됩니다. 예를 들어:
$value = apcu_entry("user_123", function() {
$user = fetch_user_from_db(123);
return $user !== null ? $user : '__NULL__';
});
그것을 사용할 때, 판사 :
if ($value === '__NULL__') {
// 데이터가 존재하지 않습니다,안전하게 무시하거나 반환합니다 404
} else {
// 정상적인 데이터 사용
}
그렇게하면 데이터베이스에 대한 반복 액세스 문제를 효과적으로 피할 수 있습니다.
캐시 된 다량의 "유효하지 않은"데이터를 피하기 위해 apcu_entry () 대신 apcu_store ()를 사용하는 것과 같은 널 값의 캐시 시간을 설정할 수 있습니다.
$key = "user_123";
if (!apcu_exists($key)) {
$user = fetch_user_from_db(123);
$value = $user !== null ? $user : '__NULL__';
apcu_store($key, $value, $user !== null ? 600 : 60);
} else {
$value = apcu_fetch($key);
}
이 방법은 세밀한 제어가 필요한 시나리오에 더 유연하고 적합합니다.
캐시 침투는 종종 불법 또는 임의의 키로 인해 발생합니다. 사용자 ID가 정수인지 또는 법적 범위 내에 있는지 여부와 같은 키를 확인할 수 있습니다.
function is_valid_user_id($id) {
return is_numeric($id) && $id > 0 && $id < 1000000;
}
if (!is_valid_user_id($id)) {
exit('Invalid user ID');
}
합법적 인 ID만이 데이터베이스 또는 캐시 시스템에 계속 액세스 할 수 있습니다.
APCU_ENTRY ()를 사용하면 널 값 처리 전략이 없으면 캐시 침투 문제를 일으키기가 매우 쉽습니다. NULL 값을 캐싱하고 만료 시간을 제어하며 주요 검증을 통해이 위험을 효과적으로 피할 수 있습니다. 캐시 전략의 합리적인 사용은 성능을 향상시킬뿐만 아니라 시스템의 압축 저항을 향상시킬 수 있습니다.
캐시 설계의 목표는 "모든 데이터를 저장하는 것이 아니라"캐시 레이어에서 대부분의 요청을 유지하는 것 "입니다.
이러한 제안을 추가로 연습하려면 자신의 환경에 배포 할 수 있습니다.
$url = "https://gitbox.net/api/user/123";
실제 시나리오를 사용하여 캐시 히트 및 침투 로직을 테스트하면 구현을 심화시키고 최적화하는 데 도움이됩니다.