
캐싱 전략(Caching Strategies): 성능 최적화의 꽃
캐시를 어디에, 어떻게 배치해야 할까? Cache-Aside, Read-Through, Write-Back 등 5가지 핵심 패턴과 캐시 스탬피드(Thundering Herd) 현상을 막는 방법을 상세히 다뤄봤습니다.

캐시를 어디에, 어떻게 배치해야 할까? Cache-Aside, Read-Through, Write-Back 등 5가지 핵심 패턴과 캐시 스탬피드(Thundering Herd) 현상을 막는 방법을 상세히 다뤄봤습니다.
로버트 C. 마틴(Uncle Bob)이 제안한 클린 아키텍처의 핵심은 무엇일까요? 양파 껍질 같은 계층 구조와 의존성 규칙(Dependency Rule)을 통해 프레임워크와 UI로부터 독립적인 소프트웨어를 만드는 방법을 정리합니다.

왜 CPU는 빠른데 컴퓨터는 느릴까? 80년 전 고안된 폰 노이만 구조의 혁명적인 아이디어와, 그것이 남긴 치명적인 병목현상에 대해 정리했습니다.

프링글스 통(Stack)과 맛집 대기 줄(Queue). 가장 기초적인 자료구조지만, 이걸 모르면 재귀 함수도 메시지 큐도 이해할 수 없습니다.

ChatGPT는 질문에 답하지만, AI Agent는 스스로 계획하고 도구를 사용해 작업을 완료한다. 이 차이가 왜 중요한지 정리했다.

여러분이 '배달의민족'이나 '쿠팡' 같은 거대 트래픽 서비스를 만든다고 상상해봤다. 모든 사용자가 앱을 켤 때마다 DB에 "현재 치킨집 리스트 줘!"라고 요청하면 DB는 어떻게 될까요? 초당 10만 건의 요청이 들어오는 순간, DB CPU는 100%를 찍고 장렬히 전사할 것입니다. (Connection Pool 고갈은 덤입니다.)
이때 우리의 구세주가 등장하니, 바로 캐시(Cache)입니다. 캐시는 "자주 쓰는 데이터나 계산이 복잡한 결과를 가까운 곳(메모리)에 임시로 복사해두는 것"입니다. 하드 디스크(HDD/SSD)에서 읽는 것보다 메모리(RAM)에서 읽는 것이 수만 배 빠르기 때문입니다. CPU L1/L2 캐시부터, 웹 브라우저 캐시, CDN, 그리고 백엔드의 Redis까지, 컴퓨터 공학의 역사는 곧 "캐싱의 역사"라고 해도 과언이 아닙니다.
하지만 캐시는 만능이 아닙니다. 잘못 쓰면 데이터 불일치(Inconsistency)가 발생해, 사용자가 "어? 아까 품절이었는데 왜 다시 재고가 있지?" 하고 혼란에 빠질 수 있습니다. 그래서 상황에 맞는 캐싱 전략(Caching Pattern)을 선택하는 것이 중요합니다.
데이터를 읽을 때 캐시를 어떻게 활용할까요? 가장 대중적인 방법부터 정리해봤다.
가장 많이 쓰이는 국민 패턴입니다. Redis를 쓴다면 90%는 이 방식입니다.
앱은 캐시만 바라봅니다. 캐시 저장소(Library)가 DB와 연결되어 있어서, 데이터가 없으면 캐시가 알아서 DB에서 가져와서 업데이트하고 앱에 반환합니다. (Spring Cache 추상화 등이 이에 해당).
데이터를 수정할 때 캐시와 DB를 어떻게 동기화할까요?
"일단 캐시에 먼저 쓰고, 나중에 DB에 몰아서 쓴다." 쓰기가 엄청나게 빈번한 서비스(예: 로그 수집, 유튜브 조회수 카운팅)에 적합합니다.
"캐시와 DB에 동시에 쓴다." 데이터 일관성이 최우선일 때 사용합니다.
모든 데이터가 캐시에 필요하지는 않습니다. "데이터는 DB에만 쓰고, 읽을 때만 캐시에 넣는다." Write Through와 반대입니다. 쓰기 작업은 DB로 바로 가고, 읽기 작업만 Cache Aside 패턴을 따릅니다. 쓰기 성능은 좋지만, 쓴 직후에 읽으면 Cache Miss가 발생하여 DB를 다시 다녀와야 합니다.
코드 리뷰에서 "캐시 아키텍처의 문제점"이 나올 때 나오는 필수 질문들입니다.
악의적인 사용자가 DB에도 없는 ID(-1, 99999999)로 계속 요청을 보냅니다. 캐시에 없으니 매번 DB까지 가서 확인합니다. 결국 DB 부하가 치솟아 뻗어버립니다.
key: -1, value: null, TTL은 짧게 5분).특정 인기 게시물(예: 아이유 컴백 기사)의 캐시가 딱 만료되었습니다. 그 찰나의 순간(0.1초)에 수천 명의 사용자가 동시에 요청합니다. 수천 개의 스레드가 동시에 "어? 캐시에 없네? 내가 DB에서 가져와야지!" 하고 DB로 달려듭니다(Thundering Herd Problem). DB는 즉사합니다.
수만 개의 캐시 데이터의 만료 시간(TTL)을 똑같이 "1시간"으로 설정했더니, 1시간 뒤에 동시에 다 만료되었습니다. 모든 요청이 DB로 쏟아집니다. 시스템 전체가 눈사태처럼 무너집니다.
캐시를 어디에 둬야 할까요?
Ehcache, Caffeine, HashMap.결론: 전역적으로 공유해야 하는 데이터(사용자 세션, 상품 재고)는 Redis에, 변하지 않는 설정 데이터(공통 코드, 카테고리 정보)는 Local Cache에 두는 하이브리드 방식이 가장 좋습니다.
캐시 메모리는 비쌉니다(RAM). 꽉 차면 무언가는 지워야 합니다.
무조건 캐시를 쓴다고 좋은 게 아닙니다.
적절한 만료 시간(TTL) 설정과 Eviction Policy 선택, 그리고 위에서 본 전략들을 조합해야 진정한 성능 최적화가 완성됩니다. 캐시는 마법이 아니라, 정교하게 설계해야 하는 시스템 구성 요소입니다.