* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
(워드프레스 해부 ⑱) 캐시
느린 계산이나 외부 API 호출을 매번 반복하면 사이트가 굼떠진다. 워드프레스엔 이걸 막는 캐시 계층이 두 종류 있다 — 트랜지언트와 오브젝트 캐시.
- 트랜지언트(transient) — 만료 시간이 있는 저장소. “이 결과를 1시간만 저장해.” 기본적으로 wp_options 테이블에
_transient_로 저장된다. 요청이 끝나도 유지된다. - 오브젝트 캐시(object cache) — 쿼리 결과 등을 메모리에 담아 한 요청 안에서 재사용. 기본은 요청이 끝나면 사라지지만, Redis/Valkey를 붙이면 요청을 넘어 영구 캐시가 된다.
나도 이 사이트에 Redis 호환 캐시(Valkey)를 붙여 오브젝트 캐시를 영구화했다. 그러면 반복되는 DB 쿼리가 메모리에서 바로 나와서, 관리자 화면과 프론트가 눈에 띄게 가벼워진다.
직접 해보기
// 비싼 계산 결과를 1시간 캐싱 (트랜지언트)
function get_expensive_data() {
$cached = get_transient( 'my_expensive_data' );
if ( $cached !== false ) {
return $cached; // 캐시 적중 — 계산 건너뜀
}
$data = run_heavy_query(); // 실제 비싼 작업
set_transient( 'my_expensive_data', $data, HOUR_IN_SECONDS );
return $data;
}
# 트랜지언트가 실제로 저장됐는지 확인
$ wp transient get my_expensive_data
# 오브젝트 캐시(Redis) 연결 상태
$ wp cache type # 'Redis' 등이 뜨면 영구 캐시 활성
✅ 확인 — 트랜지언트를 하나 저장한 뒤
wp transient get으로 값이 나오면 캐시가 동작하는 것이다. 오브젝트 캐시가 없으면 트랜지언트는wp_options에_transient_my_expensive_data로 저장되고, Redis가 붙어 있으면 메모리로 간다.
트랜지언트 vs 오브젝트 캐시 — 언제 뭘
둘 다 ‘반복 작업을 아끼는’ 캐시지만 결이 다르다. 표로 보면 헷갈리지 않는다.
| 트랜지언트 | 오브젝트 캐시 | |
|---|---|---|
| 목적 | 내가 만든 값 임시 저장 | 코어·쿼리 결과 재사용 |
| 만료 | 있음(내가 지정) | 보통 없음(무효화로 관리) |
| 저장소 | wp_options(기본) | 메모리(Redis/Valkey면 영구) |
| 쓰는 법 | set/get_transient | 대개 코어가 자동 |
트랜지언트 코드 패턴 — 없으면 만들기
전형적인 패턴은 ‘캐시 확인 → 없으면 무거운 작업 → 저장 → 반환’이다. 외부 API 결과나 무거운 집계 쿼리에 딱 맞는다.
$data = get_transient( 'cozlab_popular' );
if ( false === $data ) { // 캐시에 없으면
$data = expensive_query(); // 무거운 작업 한 번
set_transient( 'cozlab_popular', $data, HOUR_IN_SECONDS ); // 1시간 저장
}
return $data;
오브젝트 캐시를 영구화하면 — Redis/Valkey
기본 오브젝트 캐시는 요청이 끝나면 사라진다(비영구). Redis/Valkey를 붙이면 요청 사이에도 유지되고, 트랜지언트도 DB가 아니라 메모리에 저장된다. 즉 wp_options 부담이 줄고 전 요청이 빨라진다. 이 블로그도 Valkey를 붙여 이 효과를 본다 — object-cache.php 드롭인이 설치되면 코어가 알아서 이걸 쓴다.
함정 — 무효화와 쌓이는 트랜지언트
캐시의 진짜 어려움은 ‘언제 지우나‘다. 원본 데이터가 바뀌면 관련 트랜지언트를 delete_transient로 지워야 낡은 값을 안 준다. 또 만료된 트랜지언트가 wp_options에 쌓여 autoload를 무겁게 하기도 한다. 오브젝트 캐시(Redis/Valkey)를 쓰면 트랜지언트가 DB에 안 쌓여 이 문제도 자연히 줄어든다.
성능까지 봤으니, 코어 엔진 모듈의 마지막은 보안의 3종 방어 — nonce·sanitize·escape다. 이걸 모르면 확장하다 구멍을 낸다.
🔧 현장에서 — Redis 메모리는 계속 느는데 큰 Key가 없었다
운영 Redis의 Memory Usage가 지속적으로 늘어난 적이 있다. 처음엔 특정 Key에 큰 데이터가 들어갔다고 의심해 redis-cli --bigkeys로 봤는데, 실제 Key 값 크기는 매우 작았다(Access Token류는 몇 Byte 수준). 그래서 관점을 ‘Key 크기’에서 ‘Key 개수와 생명주기’로 바꿨다. prefix별로 SCAN + MEMORY USAGE + TTL로 전체 개수·평균/최대 크기·TTL 없는 Key 비율을 분석하니, 원인은 TTL 없이 계속 생성되는 작은 Key 수십만 개가 누적되는 구조였다. 넣는 시점에 TTL을 명시하도록 바꿔 해결했다.
교훈 — 메모리 사용량 ≒ Key 크기 × Key 개수. 작은 데이터라도 안 지워지면 결국 장애로 이어진다. (이 블로그도 Valkey 오브젝트 캐시를 이렇게 관리한다)
자주 묻는 질문 (FAQ)
트랜지언트와 오브젝트 캐시는 뭐가 다른가요?
트랜지언트는 만료 시간이 있는 저장이고, 오브젝트 캐시는 요청 내(또는 Redis 등으로 요청 간) 결과를 메모리에 캐싱합니다.
Redis 오브젝트 캐시를 붙이면 뭐가 좋나요?
반복 DB 쿼리를 메모리에서 돌려줘 응답이 빨라집니다. 트랜지언트도 DB 대신 Redis에 저장됩니다.

답글 남기기