캐시 계층 설계: Redis를 어디에 배치해야 할까? (Look-aside vs Write-through)

 0.1초를 위한 전쟁, 캐시(Cache) 역할

서비스의 성능 병목은 90% 이상 데이터베이스(DB)에서 발생합니다. 디스크 기반의 DB 태생적으로 메모리 기반의 애플리케이션 속도를 따라갈 없기 때문입니다. 이때 구원투수로 등장하는 것이 Redis Memcached같은 인메모리(In-Memory) 캐시 솔루션입니다.

하지만 캐시를 단순히 "DB 앞에 두는 "만으로는 충분하지 않습니다. 애플리케이션이 캐시와 DB 사이에서 데이터를 어떻게 읽고 것인가 대한 전략, 캐싱 패턴(Caching Pattern) 제대로 설계하지 않으면 오히려 데이터가 꼬이거나 성능이 저하될 있습니다. 오늘은 가장 널리 쓰이는 가지 전략, Look-aside Write-through 비교 분석해 봅니다.


Look-aside (Lazy Loading): 가장 대중적인 읽기 전략

현업에서 가장 많이 사용되는 방식입니다. 이름처럼 캐시를 (Aside) 두고 필요할 때만 데이터를 가져오는 구조입니다. '지연 로딩(Lazy Loading)'이라고도 불립니다.

작동 메커니즘

  1. Cache Hit: 플리케이션은 먼저 캐시에 데이터가 있는지 확인합니다. 있으면 바로 가져옵니다. (매우 빠름)
  2. Cache Miss: 캐시에 데이터가 없으면, 애플리케이션이 DB 직접 쿼리를 날려 데이터를 가져옵니다.
  3. Update: DB에서 가져온 데이터를 캐시에 저장하고, 사용자에게 반환합니다.

장점: 안정성과 효율성

  • 장애 대응력: Redis 다운되더라도 서비스는 추지 않습니다. 모든 요청이 DB 직접 가서 부하가 늘어나긴 하겠지만, 서비스 자체는 계속 운영될 있습니다.
  • 리소스 절약: 실제로 사용자가 요청한 데이터만 캐시에 저장됩니다. 불필요한 데이터가 메모리를 차지하는 것을 막을 있습니다.

단점: 초기 지연과 정합성

  • Cache Miss 비용: 처음 조회되는 데이터는 캐시 확인 → DB 조회캐시 저장이라는 3단계를 거쳐야 하므로 초기 응답 속도가 느립니다. 이를 해결하기 위해 서비스 오픈 전에 미리 데이터를 넣어두는 Cache Warming 작업을 하기도 합니다.
  • 데이터 불일치: DB 데이터가 변경되었을 , 캐시에는 여전히 옛날 데이터가 남아있을 있습니다. 따라서 적절한 TTL(만료 시간) 설정이 필수입니다.


Write-through: 데이터 일관성이 최우선

데이터를 (Write) 캐시와 DB 동시에 업데이트하는 방식입니다. 캐시는 항상 최신 상태를 유지하며, DB 동기화됩니다.

작동 메커니즘

  1. 애플리케이션이 데이터를 저장할 , 캐시와 DB 양쪽에 모두 씁니다.
  2. 단계가 모두 성공해야 저장이 완료된 것으로 봅니.
  3. 데이터를 읽을 때는 항상 캐시에서 가져옵니다.

장점: 데이터 정합성

  • 항상 최신 데이터: DB 캐시가 실시간으로 동기화되므, 사용자는 언제나 최신의 데이터를 조회할 있습니다. 데이터 불일치(Inconsistency) 문제가 거의 발생하지 않습니다.
  • 빠른 읽기: 데이터가 항상 캐시에 준비되어 있으므로, Look-aside 방식에서 발생하는 Cache Miss 페널티가 없습니다.

단점: 쓰기 지연과 리소스 낭비

  • 쓰기 속도 저하: 데이터를 군데(캐시+DB) 써야 하므로 저장 시간이 길어집니다. 쓰기 작업이 빈번한 서비스에서는 성능 저하의 원인이 있습니다.
  • 메모리 낭비: 자주 조회되지 않는 데이터(: 회원가입 번도 로그인 유저 정보)까지 무조건 캐시에 올라가므로, 비싼 메모리 자원을 낭비하게 됩니다. 이를 막기 위해 TTL 설정하여 사용하지 않는 데이터를 주기적으로 삭제해야 합니다.


Write-back (Write-behind): 극강의 쓰기 성능(참고)

Write-through보다 공격적인 방식입니다. 데이터를 캐시에만 먼저 쓰고, 건바이건이 아니라 일정 주기로 모아서 DB 비동기적으로 저장합니다.

  • 장점: 쓰기 쿼리가 100 들어와도 캐시에만 쓰고 끝내므로 속도가 비약적으로 빠릅니다. DB 부하를 획기적으로 줄일 있습니다.
  • 치명적 단점: 캐시 서버가 장애로 꺼지면, 아직 DB 저장되지 못한 데이터는 영구적으로 유실됩니다. 로그 수집이나 조회수 카운트처럼 일부 데이터가 날아가도 치명적이지 않은 경우에만 사용해야 합니다.


무엇을 선택해야 할까?

정답은 '서비스의 특성' 달려 있습니다.

  • 일반적인 서비스 (게시판, 상품 목록): Look-aside 패턴을 기본으로 사용하세요. 구현이 쉽고 DB 부하를 효과적으로 분산시킵니다. 여기에 절한 TTL 설정하면 데이터 불일치 문제도 대부분 해결됩니다.
  • 금융 거래, 게임 아이템 정합성이 중요한 데이터: Write-through 패턴을 고려하세요. 쓰기 속도를 약간 희생하더라도 데이터의 정확성이 중요하다면 방식이 안전합니다.
  • 대용량 로그, 실시간 위치 정보: 데이터 유실을 감수하고서라도 빠른 처리가 필요하다면 Write-back 사용할 있습니다.

현업에서는 보통 Look-aside 기본으로 하되, 빈번하게 변경되는 특정 데이터에 대해서만 Write-through 혼합하여 사용하는 하이브리드 전략 많이 채택합니다.


댓글 쓰기

다음 이전