AI Briefing

11번가 인턴의 카탈로그 리뷰 API 개선기

·2023.07.19 00:00

로컬 캐시 한계를 **global cache**와 비동기 갱신으로 줄여 응답시간과 DB 부하를 개선했다.

11번가 PDP개발팀 인턴 과제로 카탈로그 리뷰 API를 개선했다. 이 API는 카탈로그 1:N 상품 1:N 리뷰 구조가 겹친 1대N^2 형태라, 구조적으로 무거운 쿼리가 발생하고 DB 부하Read Timeout 문제를 일으켰다.

초기에는 Caffeine 기반의 로컬 캐시만 사용했지만, 서버별 캐시가 달라져 어떤 WAS에서는 캐시가 없고 다른 WAS에서는 있는 상황이 생겼다. 그 결과 동일한 요청도 인스턴스에 따라 무거운 쿼리를 다시 타게 되었고, 카탈로그 리뷰가 새로고침 시 간헐적으로 안 보이는 문제가 나타났다.

이를 해결하기 위해 global cache를 추가했다. 캐시 키는 CatalogReviewListParam, 값은 CatalogDetailReviews로 두고, 로컬 캐시와 글로벌 캐시를 함께 쓰는 2-layer cache 구조를 만들었다. 이후 요청 흐름은 로컬 캐시 우선, 미스 시 글로벌 캐시 탐색, 그래도 없으면 DB 조회 후 양쪽 캐시에 적재하는 방식으로 바뀌었다.

다음 단계에서는 호출이 빈번한 카탈로그를 미리 최신화하기 위해 Redis Sorted Set을 활용했다. 호출 빈도를 점수로 쌓아 인기 카탈로그를 찾으려 했지만, 점수가 로컬 캐시에 미스가 날 때만 증가하는 문제가 있어 유의미한 데이터가 되지 않았다. 그래서 글로벌 캐시를 로컬 캐시보다 앞단에 두는 구조로 바꾸고, 컨트롤러에는 문제가 생기면 즉시 되돌릴 수 있는 switch도 넣었다.

글로벌 캐시의 네트워크 비용은 남아 있었기 때문에, 반환과 직접 관련 없는 작업은 비동기로 전환했다. 비교 테스트는 3가지 구조로 진행했다.

  • 기존 로컬 캐시 구조
  • 글로벌 캐시를 먼저 타는 동기 구조
  • 글로벌 캐시를 먼저 타되 일부 작업을 비동기로 처리하는 구조

측정 결과, 로컬과 글로벌 캐시 모두 미스인 경우 응답시간이 153~175ms였던 동기 구조가 50~75ms로 줄어 61% 감소했다. 양쪽 캐시가 모두 히트하는 경우도 30~37ms에서 16~21ms로 줄어 44% 감소했다.

최종적으로 카탈로그 리뷰는 더 빠르게 내려오고, 새로고침 시 데이터가 비는 현상도 줄었으며, 150개로 제한하던 리뷰 수를 더 늘릴 수 있는 기반도 마련됐다. 글로벌 캐시 도입과 호출 빈도 기반 자동 최신화로 무거운 쿼리 실행 빈도가 WAS 인스턴스 수에 비례해 감소했고, 그만큼 DB 부하도 줄었다.

이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.

요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.