2025-08-08 12:53

Tags:

캐싱(Caching) 핸드북

1. 만들어진 이유: 왜 캐싱이 필요한가?

컴퓨터 시스템의 여러 구성 요소는 각기 다른 속도로 작동. CPU는 매우 빠르지만, 하드 디스크나 네트워크를 통해 데이터를 가져오는 것은 상대적으로 매우 느림. 이러한 **속도 차이(Speed Mismatch)**가 시스템 전체의 성능 저하를 유발.

비유: 똑똑한 요리사가 거대한 냉장고에서 재료를 하나씩 꺼내 요리하는 상황. 요리 속도는 빠르지만, 재료를 가지러 가는 데 시간이 오래 걸린다면 요리는 결코 빨리 완성될 수 없음. 이때 요리사 옆에 작은 보조 냉장고를 두고 자주 쓰는 재료를 미리 꺼내놓는다면, 요리 속도는 극적으로 향상될 것. 여기서 보조 냉장고가 바로 ‘캐시(Cache)‘.

즉, 캐싱은 한 번 접근했던 데이터를 더 빠른 저장소에 임시로 보관하여, 다음번에 같은 데이터를 요청할 때 느린 원본 저장소가 아닌 빠른 캐시에서 직접 제공함으로써 애플리케이션의 응답 속도를 높이고 부하를 줄이기 위해 만들어진 핵심 전략.

2. 구조: 캐시는 어떻게 작동하는가?

캐싱의 기본 작동 원리는 간단.

  1. 요청 발생: 클라이언트(예: 웹 브라우저)가 특정 데이터(예: 이미지)를 서버에 요청.

  2. 캐시 확인 (Cache Hit/Miss):

    • Cache Hit: 요청받은 데이터가 캐시에 이미 존재하면, 원본 데이터베이스까지 가지 않고 캐시에서 바로 데이터를 반환. 이는 매우 빠른 응답으로 이어짐.

    • Cache Miss: 요청받은 데이터가 캐시에 없으면, 원본 데이터베이스나 파일 시스템으로 요청을 전달하여 데이터를 가져옴.

  3. 캐시 저장 및 반환: 원본에서 가져온 데이터를 클라이언트에게 반환함과 동시에, 다음 요청을 위해 해당 데이터를 캐시에 저장.

이 과정에서 중요한 것은 어떤 데이터를, 얼마나 오래, 어떻게 저장할 것인가를 결정하는 정책.

  • 캐시 키(Cache Key): 데이터를 식별하는 고유한 값. 보통 URL, 파일명, 데이터베이스 쿼리 등이 키로 사용됨.

  • 캐시 값(Cache Value): 키에 해당하는 실제 데이터.

  • 만료 정책(Eviction Policy): 캐시 메모리는 한정되어 있으므로, 새로운 데이터를 저장할 공간이 부족할 때 어떤 데이터를 삭제할지 결정하는 규칙. (예: LRU, LFU)

3. 사용법: 어디에, 어떻게 적용하는가?

캐싱은 컴퓨터 시스템의 거의 모든 계층에서 사용됨.

  • 하드웨어 레벨:

    • CPU 캐시 (L1, L2, L3): CPU가 메인 메모리(RAM)에 접근하는 속도 차이를 줄이기 위해 CPU 칩 내부에 존재하는 초고속 메모리.
  • 운영체제 레벨:

    • 디스크 캐시 / 페이지 캐시: 하드 디스크에서 읽은 파일의 내용을 메모리에 캐싱하여 파일 접근 속도를 향상.
  • 애플리케이션 레벨:

    • 웹 브라우저 캐시: 한 번 방문한 웹사이트의 이미지, CSS, JS 파일을 사용자 컴퓨터에 저장하여 다음 방문 시 로딩 속도를 단축.

    • CDN (Content Delivery Network): 전 세계 여러 곳에 분산된 캐시 서버에 콘텐츠(동영상, 이미지 등)를 복사해두고, 사용자와 가장 가까운 서버에서 콘텐츠를 전송하여 지연 시간을 최소화.

    • 데이터베이스 캐싱: 자주 사용되는 쿼리의 결과를 메모리에 캐싱하여 데이터베이스의 부하를 줄임. (예: Redis, Memcached)

    • 애플리케이션 캐시 (인-메모리 캐시): 애플리케이션 자체 메모리 공간에 데이터를 캐싱하여 외부 시스템과의 통신 비용을 절감.

4. 심화 내용: 무엇을 더 고려해야 하는가?

캐싱을 효과적으로 사용하기 위해서는 몇 가지 중요한 문제를 고려해야 함.

  • 캐시 교체 알고리즘 (Cache Eviction/Replacement Policy):

    • LRU (Least Recently Used): 가장 오랫동안 사용되지 않은 데이터를 우선적으로 삭제. 가장 일반적인 방식.

    • LFU (Least Frequently Used): 사용 빈도가 가장 낮은 데이터를 우선적으로 삭제.

    • FIFO (First-In, First-Out): 가장 먼저 들어온 데이터부터 순서대로 삭제.

  • 캐시 무효화 (Cache Invalidation):

    • 문제점: 원본 데이터가 변경되었지만 캐시에 있는 데이터는 이전 버전일 경우, 사용자에게 **오래된 데이터(Stale Data)**가 제공되는 데이터 불일치(Inconsistency) 문제가 발생.

    • 해결 전략:

      • Write-Through: 데이터를 쓸 때 캐시와 원본 데이터베이스에 동시에 쓰는 방식. 데이터 일관성은 높지만 쓰기 속도가 느려짐.

      • Write-Back (Write-Behind): 데이터를 쓸 때 우선 캐시에만 쓰고, 특정 시점(예: 주기적, 특정 양이 찼을 때)에 모아서 원본에 한 번에 쓰는 방식. 쓰기 성능은 좋지만, 원본에 쓰기 전 시스템 장애가 발생하면 데이터가 유실될 수 있음.

      • TTL (Time To Live): 데이터에 유효 시간(예: 5분)을 설정하고, 시간이 지나면 캐시에서 자동으로 삭제되도록 하는 방식. 가장 간단하고 널리 쓰임.

  • 캐시 장애 시나리오:

    • 캐시 스톰프(Cache Stampede / Thundering Herd): 캐시된 데이터가 동시에 만료되어 수많은 요청이 한꺼번에 원본 데이터베이스로 몰리는 현상. 이는 데이터베이스에 심각한 부하를 줄 수 있음.

    • 캐시 어뷰징(Cache Abusing): 악의적인 사용자가 존재하지 않는 데이터에 대해 반복적으로 요청하여 캐시 미스를 계속 유발하고, 시스템에 부하를 주는 공격.

이 핸드북이 캐싱의 전반적인 그림을 이해하는 데 도움이 되었기를 바랍니다. 혹시 특정 캐싱 전략이나 기술에 대해 더 깊이 알아보고 싶으신 부분이 있으신가요?

References

캐싱