CS 정리

Java 대용량 데이터 처리 (5) - 캐시 계층 활용(L1, L2, DB)

문쿼리 2025. 5. 2. 16:53

5. DB만 사용 → DB + 캐시 + 계층 구조 활용 (상품 상세정보 조회)

DB 단독 조회 vs 캐시 계층 활용

  • DB 단독 조회는 사용자의 요청이 있을 때마다 매번 DB에 접근해서 데이터를 가져오는 방식.
    트래픽이 많거나 요청이 반복되는 경우, DB 부하 증가와 응답 지연이 발생할 수 있음.
  • 캐시 + 계층 구조 활용은 데이터 조회 시 우선적으로 메모리 캐시(L1),
    분산 캐시(L2) 등을 확인한 뒤, 없을 경우에만 DB 조회.
    조회 성능을 극적으로 향상시키고, DB 부하를 줄이는 효과가 있음.

 

캐시 계층 예시

  1. L1 Cache (로컬 메모리): 서버 JVM 내 ConcurrentHashMap 등
  2. L2 Cache (분산 캐시): Redis, Memcached 등
  3. DB: 최종 백엔드 데이터 소스
계층 처리 흐름
사용자 요청
   ↓
L1 캐시 확인 (JVM, local memory)
   ├─ 있음 → 즉시 반환
L1 캐시 없음
   ↓
L2 캐시 확인 (Redis, Memcached 등)
   ├─ 있음 → L1 캐시에 저장 → 반환
L2 캐시 없음
   ↓
DB 조회
   ├─ 있음 → L1 + L2 캐시에 저장 → 반환
   └─ 없음 → null 또는 에러 반환

 

Bad case: DB 단독 접근

public class ProductService {
    public Product getProductDetail(Long productId) {
        return productRepository.findById(productId);  // 매번 DB 접근
    }
}

 

Good case: 캐시 계층 활용

public class ProductService {
    private Map<Long, Product> localCache = new ConcurrentHashMap<>();
    private RedisTemplate<String, Product> redisTemplate; // Spring Redis 사용 가정
    private ProductRepository productRepository;

    public Product getProductDetail(Long productId) {
        // 1. L1 캐시 확인
        Product product = localCache.get(productId);
        if (product != null) return product;

        // 2. L2 캐시 확인 (Redis)
        product = redisTemplate.opsForValue().get("product:" + productId);
        if (product != null) {
            localCache.put(productId, product);  // L1 캐시에도 반영
            return product;
        }

        // 3. DB 접근
        product = productRepository.findById(productId);
        if (product != null) {
            redisTemplate.opsForValue().set("product:" + productId, product, Duration.ofMinutes(10));
            localCache.put(productId, product);
        }

        return product;
    }
}

 

요약 정리

  • DB만 사용할 경우 모든 요청이 DB로 집중되어 성능 병목이 발생할 수 있음.
  • 캐시 계층을 활용하면 응답 속도 향상, 트래픽 분산, DB 비용 절감 효과가 있음.
  • L1 (JVM 캐시), L2 (Redis 등 분산 캐시), DB로 구성된 다단계 계층 구조를 통해 효율적으로 데이터 조회 가능.
  • 캐시 무효화 전략 (TTL, 갱신, 삭제)과 장애 시 fallback 로직도 함께 고려해야 함.

주의사항

  1. 캐시 계층 활용은 적합한 구조의 데이터에서만 활용해야함.
    Good :자주 변경되지 않고, 조회의 빈도가 높을 수록 활용도가 높아짐.
    (상품정보, 주소, 사용자 세션 정보, 통계, 공지사항 등)
    Bad :반대로 자주 변경되거나, 개인정보를 포함하고 있거나, 데이터 무결성이 중요한 경우 사용해서는 안됨.
    (실시간 재고 수불, PII, 금융 거래 등)
  2. 캐싱 갱신 전략
    wirte-through :캐시와 DB에 동시에 저장, 안정적이고 느림
    (일관성이 중요할 때, 로그인한 사용자 권한 정보, 주문 상태 변경 등)
    write-back :캐시먼저 저장 후 비동기로 DB저장, 빠르지만 유실가능성 있음
    (성능이 중요할 때, 약간의 유실을 감수할 수 있을때, 게시물 조회 수, 로깅 등)