최신 웹 응용 프로그램에서 분산 아키텍처는 시스템 가용성 및 확장 성을 향상시키는 주류 방법이되었습니다. 그러나 분산 환경에서 제기 한 과제 중 하나는 다음과 같습니다. 분산 노드 간의 캐시 상태를 올바르게 관리 할 수없는 경우 일관성이없는 데이터로 인해 오류, 사용자 경험이 저하 및 보안 위험이 발생할 수 있습니다.
이 기사는 PHP의 APCU_ENTRY 기능을 사용하여 분산 시스템에서 효율적이고 일관된 캐싱 메커니즘을 구현하는 방법을 소개합니다.
APCU_ENTRY는 CACHED 값을 원자 적으로 얻거나 캐시가 존재하지 않는 경우 캐시를 생성하고 저장하기 위해 PHP APCU 확장자가 제공하는 편리한 기능입니다. 함수 서명은 다음과 같습니다.
mixed apcu_entry(string $key, callable $generator, int $ttl = 0)
$ 키 : 캐시 키 이름.
$ 생성기 : 캐시 항목이 존재하지 않을 때 호출 된 함수, 캐시 된 값을 생성하는 데 사용됩니다.
$ ttl : 캐시 시간, 초. 0은 만료 된 것을 의미합니다.
이 함수는 스레드 안전 특성을 가지며 멀티 스레드 (또는 동시) 환경에서 "충격적인"효과를 피하여 캐시 값이 한 번만 생성되도록합니다.
기본적으로 APCU는 로컬 메모리를 기반으로하며 서버에서 공유 할 수 없습니다. 따라서 여러 PHP-FPM 노드 중에서 각 노드의 APCU가 분리됩니다.
예를 들어:
서버 A는 캐시 키 key user_123_profile을 요청하고 생성 로직을 실행합니다.
서버 B는이 키를 다시 요청하고 APCU는 서버 A의 로컬 메모리에만 존재하기 때문에 캐시에 도달하지 않습니다.
이 경우 여러 노드가 동시에 데이터를 가져 와서 로컬 APCU 캐시에 쓰려고하면 중복 리소스 소비 및 가능한 데이터 불일치가 발생합니다.
APCU 및 Redis를 사용하여 APCU를 노드의 첫 번째 레벨 캐시 (L1 캐시) 로, Redis는 공유 캐시 레이어 (L2 캐시) 로 사용할 수 있습니다.
각 노드는 로컬 APCU에서 데이터를 검색하려는 시도의 우선 순위를 정합니다.
APCU가 발생하지 않으면 APCU_ENTRY를 사용하여 데이터 생성 로직을 한 번만 호출하십시오.
apcu_entry 의 세대 논리에서 :
먼저 Redis가 이미 데이터를 가지고 있는지 확인하십시오.
Redis가 닿으면 Redis에서로드하고 APCU에 저장하십시오.
Redis가 누락되면 데이터베이스 또는 다른 소스에서 가져 와서 Redis 및 APCU에 저장하십시오.
function getUserProfile($userId) {
$cacheKey = "user_profile_$userId";
return apcu_entry($cacheKey, function() use ($cacheKey, $userId) {
// Redis 분산 캐시로
$redis = new Redis();
$redis->connect('gitbox.net', 6379);
$redisKey = "global_cache:$cacheKey";
$cached = $redis->get($redisKey);
if ($cached !== false) {
return json_decode($cached, true);
}
// 데이터베이스에서 데이터로드를 시뮬레이션합니다
$profileData = loadUserProfileFromDB($userId);
// 구하다 Redis(만료 시간을 설정하십시오,예를 들어10분)
$redis->setex($redisKey, 600, json_encode($profileData));
return $profileData;
}, 60); // APCu 은닉처60두번째
}
위의 방법을 통해 APCU_ENTRY는 첫 번째 요청이 이루어질 때 각 노드가 데이터로드 로직을 한 번만 입력하고 데이터베이스의 반복 쿼리를 피합니다. Redis의 존재는 노드에서 캐시 일관성을 보장합니다.
데이터 일관성을 향상시키기 위해 다음 전략을 채택 할 수 있습니다.
통일 된 만료 시간 : Redis와 APCU의 TTL이 비교적 일관성이 있는지 확인하고 "더러운 읽기"를 피하십시오.
버전 번호를 사용하여 데이터를 제어하십시오 . 캐시 데이터에 버전 번호 또는 타임 스탬프를 추가하여 읽을 때 최신임을 확인하십시오.
활성 실패 메커니즘 : 예를 들어, 사용자 데이터가 업데이트 된 후 모든 노드에 해당 APCU 캐시를 지우도록 통지합니다 (Redis Publish/Subscribe에서 구현할 수 있음).
APCU는 분산 환경에서 데이터를 직접 공유 할 수는 없지만 APCU_ENTRY 의 스레드 안전 메커니즘을 통해 Local + Global Cache와 협력하여 작동하는 효율적인 캐시 시스템을 구축 할 수 있습니다. Redis와 같은 공유 캐싱 도구와 결합하여 데이터베이스 부하를 효과적으로 줄이고 시스템 성능을 향상 시키며 데이터 일관성을 최대한 유지할 수 있습니다.
이 모델은 특히 사용자 정보, 구성 데이터, 제품 세부 사항 등과 같은 비즈니스 시나리오에 특히 적합합니다. 판독 빈도가 높고 업데이트 빈도가 낮습니다. 고성능 PHP 분산 시스템을 구축하는 것이 중요한 수단 중 하나입니다.