카카오테크 부트캠프

Redis 캐시 키 설계 관련 보고서: 사용자 domain 정보 처리 전략

kanado 2025. 7. 11. 15:22

문제 정의

현재 다음과 같은 방식으로 Redis 키를 구성하여 페이지네이션된 TuningReport 리스트를 캐싱하고 있음

public String pageListKey(String domain) {
    return String.format("reports:domain=%s:page=0:size=10:sort=%s:list", domain, TuningReportSortType.LATEST);
}

그러나 사용자의 domain 정보는 MySQL에서 조회해야 하며, 이는 캐시 키 생성 자체가 DB 조회를 필요로 한다는 점에서 Redis 도입의 목적(=DB 부하 감소)을 훼손하고 있음.

👉 DB 부하를 줄이기 위한 캐시인데, 키 생성을 위해 다시 DB를 조회하게 되면 캐시의 의미가 퇴색된다.
즉, "키를 만들기 위해 필요한 정보 자체가 DB에서 온다”

 

요구사항 요약

  • Redis 캐시 조회 이전에 DB 조회가 발생하지 않아야 함
  • domain 정보를 기준으로 구성된 캐시 키(reports:domain=...)를 유지하거나 유사한 효과를 유지할 것
  • domain 정보는 사용자의 정체성과 밀접하며, 빈번히 변경되지 않음

 

고려한 해결 방안

1. 사용자의 domain 값을 Redis에 미리 캐싱해두기

  • Redis에 user:{userId}:domain 형태로 사용자 domain 값을 1차 캐시로 저장
  • 캐시 미스일 경우에만 DB에서 조회하고, Redis에 다시 저장
  • 이후 보고서 키 구성 시에는 Redis에서 domain을 조회하여 사용
String domain = redisTemplate.opsForValue().get("user:" + userId + ":domain");
if (domain == null) {
    domain = userRepository.findDomainById(userId);
    redisTemplate.opsForValue().set("user:" + userId + ":domain", domain, Duration.ofHours(1));
}
String redisKey = pageListKey(domain);

장점

  • DB 접근 최소화
  • 기존 키 패턴 (domain 기준 키) 유지 가능
  • 사용자 속성이 자주 변하지 않는다면 TTL 관리만으로 충분

단점

  • 사용자 domain 변경 시 캐시 무효화 혹은 갱신 로직 필요 (방지하기 쉬움)

2. 클라이언트가 API 호출 시 domain 값을 함께 전달

GET /api/reports?domain=cat_lover

장점

  • 서버는 키 생성 시 DB/캐시에 접근할 필요 없음
  • 성능상 가장 빠름

단점

  • 기존에 이미 API 요청 로직이 완성되어 있기 때문에, 이 변경은 프론트엔드 코드 전반에 영향을 미치며 리소스 소모가 큼

3. 캐시 키에 userId를 사용하고 내부에서 domain resolve

String key = String.format("reports:user=%s:list", userId);
  • 도메인 기반이 아닌 유저 개인 키를 기준으로 캐싱

장점

  • 키 생성 단순
  • domain 정보가 필요 없음

단점

  • 같은 도메인 사용자 간 캐시 공유 불가 → 캐시 중복 증가 / 메모리 사용량 증가
  • 데이터 사용량이 급증하며, 캐시 효율성 저하

 

최종 선택: 1차 캐시로 사용자 domain 값 Redis에 캐싱

⭐️ 사용자의 domain 정보는 변경이 드물며식별자로써 키 생성에 반드시 필요한 속성이다.

따라서 이 정보를 Redis에 먼저 캐싱하고 활용하는 전략은 캐시 설계 원칙을 지키면서도 성능을 최대화할 수 있는 가장 실용적인 접근이다.

후속 처리로 사용자 domain 변경 시 다음 캐시들을 무효화하거나 갱신할 것이 있다.

 

결론

현재 Redis 키 생성 과정에서 발생한 성능 역행 문제를 해결하기 위해, 1차 캐시로 사용자 domain을 Redis에 저장하고, 이를 통해 캐시 키를 구성하는 전략을 도입함.

이 방식은 DB 부하를 줄이면서 기존 도메인 기반 캐싱 구조를 유지할 수 있으며, 확장성과 성능 면에서 가장 이상적인 선택이다.

 

끝.