Q3-1
어떤 문제 상황이었나요? 왜 캐시가 필요했나요?
핵심 포인트
- 3D 뷰어에서 소재(Material) 변경 시 동일 텍스처 이미지 URL을 서버에서 중복 요청
- 단일 화면에 동일 텍스처가 여러 곳에서 거의 동시에 요청되는 상황 (예: 같은 패턴의 소재가 여러 슬롯에 들어감)
- 네트워크 트래픽 + 서버 비용 + 체감 응답 지연이 누적
- 단순 결과 캐시만으론 부족. 요청이 동시에 들어오는 race가 핵심 문제
모범 답안먼저 답해보고 펼치기
3D 뷰어에서 소재를 바꿀 때마다 텍스처 이미지를 서버에서 받아오는 흐름이 있었어요. 화면에 동일한 패턴의 소재가 여러 슬롯에 동시에 들어가는 경우가 흔했는데, 그 때 같은 텍스처 URL이 거의 동시에 4~5번씩 요청되는 일이 자주 일어났습니다. 네트워크 패널을 보면 같은 url이 동시에 떠 있고, 서버 응답을 기다리는 동안 사용자에게 보이는 첫 프레임이 의도보다 늦게 그려졌어요.
처음엔 "결과 캐시(Map)만 있으면 두 번째부터는 캐시가 잡혀서 괜찮겠지"라고 생각했는데, 실제로는 동시에 첫 요청이 진행 중일 때 두 번째·세 번째가 들어오면 모두 캐시 미스로 분류되어 똑같은 fetch가 4번 떠버렸어요. 결과 캐시는 "이미 끝난 작업"만 막을 뿐, "지금 진행 중인 작업"은 못 막는다는 게 문제의 본질이었습니다.
이 답변, 어땠나요?
꼬리 질문
- Q-a. 백엔드에 캐시 헤더(Cache-Control)를 다는 게 더 단순하지 않나요?
브라우저 HTTP 캐시는 같은 url 동시 요청을 dedupe해 주는 보장이 없습니다. 캐시 헤더가 떠 있어도 동시 요청은 그대로 4번 나갈 수 있어요. 클라이언트 레이어의 dedupe가 별도로 필요했습니다.
- Q-b. 이미 React Query 같은 라이브러리가 dedupe를 해 주지 않나요?
맞습니다. 다만 우리 텍스처 로딩은 React 컴포넌트가 호출하는 게 아니라 3D 엔진 내부에서 호출하는 흐름이라 React Query에 통합하기가 부자연스러웠어요. 엔진 모듈 안에 직접 캐시 레이어를 두는 게 응집도가 높았습니다.
- Q-c. 서비스 워커에서 dedupe하는 옵션은 검토하셨나요?
검토했지만 SW는 도입 자체가 별도 의사결정이고, 디버깅 비용도 커서 단순한 인메모리 캐시 레이어가 비용 대비 효과가 가장 컸어요.
CS · 이론
- Thundering herd / Cache stampede: 캐시 만료·미스 직후 동일 요청이 동시에 백엔드로 몰리는 현상. 분산 시스템에서 잘 알려진 문제
- Request coalescing / Request deduplication: 같은 요청을 하나로 합치는 기법. 본 토픽의 핵심
- HTTP 캐싱과 동시 요청: HTTP 캐시는 응답 후 저장이 핵심이지 진행 중 요청 dedupe는 보장 안 함
- React Query / SWR의 dedupingInterval: 라이브러리가 같은 문제를 어떻게 푸는지 비교 사례