Cache-Aside는 애플리케이션이 캐시와 데이터베이스를 직접 확인하고 관리하는 캐싱 전략입니다.
데이터를 조회할 때 먼저 캐시를 확인합니다.
클라이언트
↓
애플리케이션
↓
캐시 조회
캐시에 데이터가 있으면 바로 반환합니다.
캐시에 데이터 있음(Cache Hit)
→ 캐시 데이터 반환
캐시에 데이터가 없으면 데이터베이스에서 조회한 뒤, 결과를 캐시에 저장하고 반환합니다.
캐시에 데이터 없음(Cache Miss)
→ DB 조회
→ 조회 결과를 캐시에 저장
→ 데이터 반환
전체 흐름은 다음과 같습니다.
1. 캐시 조회
2. 데이터가 있으면 반환
3. 데이터가 없으면 DB 조회
4. DB 조회 결과를 캐시에 저장
5. 데이터 반환
의사 코드로 표현하면 간단합니다.
public Product getProduct(Long productId) {
Product product = cache.get(productId);
if (product != null) {
return product;
}
product = productRepository.findById(productId);
cache.set(productId, product);
return product;
}
Redis를 사용한다고 가정하면 다음과 같은 구조입니다.
public ProductResponse getProduct(Long productId) {
String key = "product:" + productId;
ProductResponse cachedProduct = redisTemplate.get(key);
if (cachedProduct != null) {
return cachedProduct;
}
Product product = productRepository.findById(productId)
.orElseThrow(ProductNotFoundException::new);
ProductResponse response = ProductResponse.from(product);
redisTemplate.set(key, response, Duration.ofMinutes(10));
return response;
}
왜 Cache-Aside를 사용하는가?
데이터베이스 조회는 캐시 조회보다 상대적으로 느리고 비용이 큽니다.
특히 다음과 같은 데이터는 반복해서 조회될 가능성이 높습니다.
- 상품 상세 정보
- 게시글
- 사용자 프로필
- 카테고리
- 설정 정보
- 인기 콘텐츠
매 요청마다 데이터베이스를 조회하는 대신 자주 사용하는 데이터를 Redis 같은 캐시에 저장하면 다음 효과를 얻을 수 있습니다.
- 응답 시간 단축
- 데이터베이스 부하 감소
- 동일 데이터의 반복 조회 방지
- 순간적인 트래픽 대응력 향상
데이터가 변경되면 어떻게 할까?
Cache-Aside에서 조회보다 어려운 부분은 데이터 변경입니다.
예를 들어 데이터베이스의 상품 가격을 변경했지만 캐시에는 이전 가격이 남아 있을 수 있습니다.
DB 가격 : 15,000원
캐시 가격 : 10,000원
이를 캐시와 데이터베이스의 데이터 불일치라고 합니다.
일반적으로 데이터를 변경할 때는 다음과 같이 처리합니다.
1. DB 데이터 변경
2. 기존 캐시 삭제
@Transactional
public void updateProduct(
Long productId,
UpdateProductRequest request
) {
Product product = productRepository.findById(productId)
.orElseThrow(ProductNotFoundException::new);
product.update(request);
redisTemplate.delete("product:" + productId);
}
이후 첫 번째 조회 요청에서 캐시 미스가 발생하고 최신 데이터를 다시 저장합니다.
캐시 삭제
→ 다음 조회에서 Cache Miss
→ DB에서 최신 데이터 조회
→ 최신 데이터를 캐시에 저장
DB 변경 후 캐시 데이터를 직접 갱신할 수도 있지만, 로직이 복잡해질수록 잘못된 데이터가 저장될 가능성이 있습니다. 그래서 우선 DB를 변경하고 캐시를 삭제하는 방식이 자주 사용됩니다.
단, DB 트랜잭션이 최종적으로 커밋되기 전에 캐시를 삭제하면 롤백 시 문제가 생길 수 있으므로 실제 구현에서는 트랜잭션 커밋 이후 캐시를 삭제하는 방법도 고려해야 합니다.
Cache-Aside의 장단점
장점
- 실제로 조회되는 데이터만 캐시에 저장된다.
- 캐시 장애가 발생해도 DB를 통해 서비스를 계속 제공할 수 있다.
- 캐시 저장 시점과 TTL을 애플리케이션이 통제할 수 있다.
- 구현 방식이 비교적 단순하다.
단점
- 최초 조회에서는 반드시 Cache Miss가 발생한다.
- 애플리케이션 코드에 캐시 처리 로직이 들어간다.
- DB와 캐시의 데이터가 일시적으로 불일치할 수 있다.
- 캐시 만료 순간에 요청이 몰리면 DB 부하가 급증할 수 있다.
- 캐시 장애 시 모든 요청이 DB로 몰릴 수 있다.
'CS 정리' 카테고리의 다른 글
| DNS TTL이란? TTL을 300초로 설정하면 정말 5분 뒤에 IP가 바뀔까? (0) | 2026.08.31 |
|---|---|
| Cache-Aside를 실무에서 사용하면 어떤 문제가 생길까? (0) | 2026.08.29 |
| 분산 트랜잭션이란? MSA에서 발생하는 문제와 Saga 패턴 (0) | 2026.08.24 |
| CQRS란? 읽기와 쓰기를 분리하는 이유 (0) | 2026.08.24 |
| 서킷 브레이커(Circuit Breaker)란? 외부 API가 죽었을 때 우리 서버까지 같이 죽지 않게 하기 (0) | 2026.08.23 |