피드로 돌아가기
올리브영 테크블로그Backend
원문 읽기
올리브영은 왜 선물하기를 개편했을까? Part - 2
올리브영이 @DisplayCaching 커스텀 어노테이션과 Redis 분산 락을 도입해 선물하기 페이지 로딩 시간을 1.74초에서 5밀리초로 단축
AI 요약
Context
선물하기 영역에서 @CircuitBreaker와 @Cacheable 두 개의 어노테이션을 개별 사용하면서 캐시 키·TTL 설정이 불명확했고, SpEL(Spring Expression Language) 문자열 기반 설정으로 인한 IDE 지원 부족과 실수 유발 가능성이 높았다. Redis의 hash 타입 데이터도 활용할 수 없어 새로운 기능 추가 시마다 어려움을 겪었다.
Technical Solution
- @DisplayCaching 커스텀 어노테이션 개발: displayCacheInfo(캐시명·TTL·데이터 타입), dateTimeKeySuffix(일자별 버전), throwWhenReadFail(예외 발생 여부), putDataAfterProceed(폴백 결과 캐시 저장 여부)를 속성으로 제공해 기존 2개 어노테이션을 통합
- @DisplayCachingKey 파라미터 어노테이션: 함수 파라미터를 캐시 키에 동적으로 포함 가능하게 구현하며, forHashKey=true 설정 시 Redis hash 타입의 해시 키로 활용 가능
- DisplayCacheInfo 열거형: 각 캐시별로 key("display:foo" 형식), ttl(900초 등), redisDataType(VALUE 또는 HASH) 속성을 선언형으로 정의해 일관성 있는 관리 제공
- DateTimeKeySuffixType 열거형: NOT_USE 또는 LOCAL_DATE 선택으로 캐시 키 마지막에 현재 시간 기반 접미사(-yyyyMMdd) 자동 생성해 일자별 버전 관리 지원
- Redis 분산 락(FallbackLockOption): LOCK_10S_CHECK_EVERY_1S 설정으로 폴백 로직 실행 중 다른 요청들은 1초마다 Redis 데이터 적재 여부를 확인하도록 구현해 캐시 스탬피드 방지
Impact
- 평균 페이지 로딩 시간 1.74초 → 5밀리초로 단축
- 분산 락 도입 후 폴백 로직 정확히 1회 실행 확인
- 최초 락 획득 로직 3.25초 소요 중 비슷한 시점 요청은 DB 호출 없이 Redis 체크 후 3초 후 빠른 응답 확보
Key Takeaway
Redis 캐싱을 활용하는 고트래픽 서비스에서 커스텀 어노테이션으로 캐시 설정을 선언형으로 통합하고 분산 락을 적용하면, 개발자 실수를 줄이면서 캐시 스탐피드 문제를 동시에 해결할 수 있다.
실천 포인트
Redis 캐시를 사용하는 Spring Boot 백엔드 팀에서 @DisplayCaching처럼 캐시명·TTL·폴백 전략을 하나의 어노테이션으로 관리하는 커스텀 모듈을 만들고, 분산 락으로 폴백 중복 실행을 방지하면 기존의 여러 어노테이션 조합 방식 대비 설정 오류를 줄이면서 동시성 문제까지 해결할 수 있다.