워드프레스에는 기본으로 오브젝트 캐시가 있습니다. 옵션 · 포스트 · 메타 · 텀 조회가 전부 이 계층을 거치므로, 한 요청 안에서 같은 값을 열 번 읽어도 DB 에는 한 번만 갑니다. 다만 기본 구현은 요청이 끝나면 사라집니다 — PHP 프로세스의 메모리에만 있기 때문입니다.
Redis 같은 영속 백엔드를 붙이는 것은 이 캐시를 요청 사이에도 살려 두는 일입니다. 그것이 전부이고, 그래서 무엇이 좋아지고 무엇이 그대로인지가 정확히 정해집니다.
줄어드는 것과 그대로인 것
왼쪽 첫 줄이 핵심입니다. 4초짜리 쿼리에 캐시를 얹으면 두 번째 요청부터 빨라집니다. 첫 요청은 여전히 4초를 내고, 캐시가 만료되거나 무효화될 때마다 누군가 다시 그 4초를 냅니다. 앞 회차에서 느린 쿼리와 중복 쿼리를 구분한 이유가 여기서 드러납니다 — 중복 쿼리는 캐시로 사라지고, 느린 쿼리는 고쳐야 합니다.
오른쪽에서 눈여겨볼 것은 로그인 사용자 화면입니다. 로그인 요청은 페이지 캐시를 우회하므로 매번 PHP 를 타는데, 오브젝트 캐시는 바로 그 경로에서 값을 합니다. 관리자 화면이 무겁다는 호소가 이 계층을 붙이고 나서 달라지는 경우가 많은 이유입니다.
붙인 뒤 확인할 것
드롭인이 실제로 유효한지, 연결이 살아 있는지부터 봅니다. WP-CLI 로 상태를 확인하는 것이 가장 빠릅니다.
wp redis status
wp cache flush # 배포 직후 한 번 — 낡은 구조의 값이 남지 않게
그다음 히트율을 봅니다. 히트율이 낮게 유지된다면 캐시가 계속 비워지고 있거나, 키가 매번 달라 아무것도 재사용되지 않고 있다는 뜻입니다. 후자는 코드가 캐시 키에 타임스탬프나 랜덤 값을 섞을 때 생깁니다.
직접 캐시를 쓸 때는 미스와 false 를 구분합니다. 네 번째 인자로 넘긴 변수에 실제 히트 여부가 담깁니다.
$value = wp_cache_get( 'acme_report', 'acme', false, $found );
if ( ! $found ) {
$value = acme_build_report(); // 느린 부분은 여전히 여기서 한 번 돈다
wp_cache_set( 'acme_report', $value, 'acme', 300 );
}
$found 없이 false === $value 로만 판정하면, 값이 진짜 false 인 경우와 캐시 미스가 구분되지 않아 매 요청마다 재계산하게 됩니다. 히트율이 이상하게 낮을 때 가장 먼저 의심할 코드입니다.
영속화하면 안 되는 그룹
모든 값이 요청을 넘겨 살아남아야 하는 것은 아닙니다. 한 요청 안에서만 의미 있는 값 — 계산 중간 결과, 요청 단위 카운터 — 을 Redis 에 밀어 넣으면 왕복 비용만 늘고 정합성 문제까지 생깁니다.
wp_cache_add_non_persistent_groups( [ 'acme_runtime' ] );
이 선언은 플러그인 로드 시점에 해 둡니다. 반대로 여러 사이트가 같은 Redis 를 공유한다면 키 접두사와 DB 인덱스를 분리해 서로의 값을 덮어쓰지 않게 합니다 — 개발 환경에서 특히 자주 겪는 사고입니다.
캐시 계층 구성은 서버 · 인프라 아카이브에서 더 다루고, Redis 도입과 검증까지 포함한 작업 범위는 최적화 지원 사업에 정리돼 있습니다.
다음 회차
오브젝트 캐시는 코어가 알아서 채우고 비웁니다. 반면 내가 직접 저장하는 캐시는 비우는 일까지 내 책임입니다 — 다음 회차는 트랜지언트와 무효화 설계입니다.