infra
Platform

모듈 맵

[SW Eng] 용어사전 — Cache / 성능 / 세션

0 / 38 완료

펼치기
0 / 38 완료0%

PM·SRE를 위한 소프트웨어 엔지니어링 · 34 / 38

[SW Eng] 용어사전 — Cache / 성능 / 세션

Redis/캐시 전략(write-through·cache-aside)·TTL/LRU·캐시히트/미스·세션 외부화·부하 테스트·TPS/QPS·병목 등 성능 용어를 빠르게 해독합니다

🚨INCIDENT ALERT
HIGH

이벤트 오픈 직후 서비스가 느려집니다. "캐시 히트율이 20%밖에 안 돼서 DB가 부하를 다 받아요." 인스턴스를 늘렸더니 이번엔 "로그인이 자꾸 풀려요"(세션이 로컬에). "TPS가 한계라는데 어디가 병목인지 모르겠어요." PM·인프라인 당신은 캐시·성능·세션 용어를 알아야 이 문제들의 방향을 잡습니다. 이 사전은 캐시·성능·세션 용어를 빠르게 해독합니다. 깊은 내용은 Redis·성능 관련 모듈로 연결합니다.

이번 챕터에서 배울 것
  • 1캐시 전략(cache-aside·write-through 등)과 히트/미스를 설명할 수 있다
  • 2TTL·LRU·eviction으로 캐시 동작과 용량을 이해할 수 있다
  • 3세션 외부화가 수평 확장에 필요한 이유를 설명할 수 있다
  • 4부하/스트레스/스파이크 테스트와 TPS/QPS·병목으로 성능을 진단할 수 있다

캐시 — 전략과 동작

Cache-Aside 패턴 Hit vs Miss 흐름 — 히트율·TTL·LRU·Eviction확대

위 그림처럼 Cache-Aside는 캐시 히트 시 DB를 거치지 않아 빠르고, 미스 시 DB 조회 후 캐시에 저장해 다음 요청을 히트로 전환합니다. 히트율이 낮으면(50% 미만) 캐시 키 설계·TTL·용량을 점검하고, 쓰기 시 캐시 무효화는 앱이 직접 관리합니다.

💡개념

무엇을 어떻게 캐시하나

용어한 줄 뜻비고중요도
Redis / Memcached인메모리 캐시·저장소대표 → 캐시(Cache) 전략, 세션 스토어, Pub/Sub 실무 패턴★★
Local / Distributed Cache프로세스 내 / 공유 캐시분산=일관성↑★★
Cache Hit / Miss / Eviction적중 / 빗나감 / 쫓겨남히트율 핵심 지표★★★
TTL / LRU수명 / 오래안쓴것부터 제거용량 관리★★
Write-through / Write-back / Read-through / Cache-Aside캐시 쓰기·읽기 전략Cache-Aside 흔함★★
CDN Cache / Browser Cache / ETag / Last-Modified가장자리·브라우저 캐시정적 가속 → 웹방화벽 403 분석과 CDN 캐시 관리 실무★★

핵심: 캐시는 '자주 읽고 덜 바뀌는' 데이터에 효과적입니다. 히트율이 낮으면(많이 miss) 캐시 의미가 없으니 키 설계·TTL·용량을 점검합니다. 쓰기 시 캐시-DB 일관성(무효화)이 캐시의 가장 어려운 부분입니다(캐시(Cache) 전략, 세션 스토어, Pub/Sub 실무 패턴).

캐시가 응답을 빠르게 하는 법 — 조회·적중·무효화

💡개념

요청 하나가 캐시를 지나는 5단계 — hit·miss·저장·무효화·축출

캐시가 "빠르다"는 건 알지만, 정작 요청 하나가 들어왔을 때 캐시 안에서 어떤 판단이 순서대로 일어나는지를 그려보지 않으면 히트율·stale·스탬피드 같은 문제가 왜 생기는지 감이 안 옵니다. 캐시의 핵심은 단 하나 — 원본(느린 DB·API)보다 가까운 곳에 답을 복사해 두고, 다음엔 그 사본으로 답하는 것입니다. 아래 흐름은 조회(hit/miss)부터 쓰기·무효화·축출까지, 캐시가 응답을 빠르게 하면서 동시에 어떤 위험을 떠안는지를 한눈에 보여줍니다.

TEXT
[앱]  getProduct(42) 요청
   │
   ① 캐시 조회   GET product:42
   │
   ├─ HIT (값 있고 안 만료)  ─────────→ 즉시 반환 (수십 마이크로초, DB 안 감)
   │
   └─ MISS (없거나 TTL 만료)
         │
         ② 원본 조회   SELECT * FROM product WHERE id=42   (수 ms~수십 ms)
         │
         ③ 캐시에 저장  SET product:42 ... EX 300          (TTL 300초 부여)
         │
         ▼ 반환 → 이후 같은 키 요청은 ①에서 HIT

  [쓰기]  updateProduct(42)
     ├─ write-through : DB와 캐시를 즉시 함께 갱신 (동기, 일관성↑)
     ├─ write-back    : 캐시만 먼저, DB는 나중에 (빠르나 유실 위험)
     └─ 무효화        : DEL product:42 → 다음 조회 때 새로 채움 (가장 흔함)

  [용량 초과]  maxmemory 도달 → LRU·LFU로 오래·덜 쓴 키부터 축출(eviction)

각 단계가 하는 일과, 여기서 어긋나면 나타나는 증상:

단계하는 일여기서 어긋나면
① 조회(hit/miss 판정)캐시 키로 값이 있고 안 만료됐는지 확인. 있으면 원본을 건너뜀키를 너무 잘게 설계(사용자별·파라미터별)하면 대부분 miss → 히트율 바닥, 캐시 무의미
② miss 시 원본 조회없을 때만 느린 DB·API로 감. 정상 캐시는 이 경로가 소수인기 키가 동시에 만료되면 수많은 요청이 한꺼번에 miss로 DB에 몰림 = cache stampede(원본 휘청)
③ 캐시에 저장 + TTL읽어온 값을 캐시에 넣고 만료 시간 부여. TTL이 일관성·히트율을 동시에 좌우TTL 너무 짧으면 금방 miss(효과↓), 너무 길면 원본과 어긋난 옛 값(stale)을 오래 반환
④ 쓰기·무효화원본이 바뀔 때 캐시를 함께 갱신하거나 지워 stale 방지무효화를 빠뜨리면 DB는 바뀌었는데 캐시가 옛 값을 계속 반환 — "DB엔 맞는데 화면은 옛날 값"
⑤ 축출(eviction)용량이 차면 LRU(오래 안 쓴)·LFU(덜 쓴) 키부터 밀어냄용량이 작으면 채우자마자 쫓겨나(잦은 eviction) 히트율이 안 오름

즉 캐시는 "빠른 저장소"가 아니라 "원본의 사본을 가까이 두는 규칙" 이고, 그 대가로 원본과 어긋날(stale) 위험·동시 miss 폭주(stampede) 위험을 떠안습니다. 그래서 문제를 좁힐 때는 먼저 어느 계층 캐시인지(브라우저 → CDN → 앱 인메모리 → 분산 캐시(Redis) → DB 버퍼)를 정하고, 그 계층의 히트율(효과 있나)·stale(정확한가)·stampede·지연(위험한가) 세 축으로 봅니다. 히트율이 높은데도 느린 순간이 있다면 원인은 캐시 바깥이 아니라 캐시 내부 동작에 있습니다(아래 심화 참고).

세션 · 연결 재사용

캐시 쓰기·읽기 전략 4종 비교(Cache-Aside·Read-through·Write-through·Write-back)확대

위 그림처럼 실무 기본은 Cache-Aside(앱이 직접 캐시 관리)이며, Write-through는 강한 일관성이 필요할 때, Write-back은 쓰기 부하가 극심할 때 선택합니다. 쓰기가 많은 데이터는 캐시 효과보다 일관성 복잡도가 올라가므로 캐시 대상 선정이 중요합니다.

💡개념

상태와 연결을 효율적으로

용어한 줄 뜻비고중요도
Session Store / Sticky Session세션 저장소 / 같은서버 고정외부화 → 12-Factor App★★★
Token Cache / CDN Cache / Browser Cache토큰·CDN·브라우저 캐시계층별 캐시★★
Compression / Gzip / Brotli응답 압축전송량↓★★
Lazy / Eager Loading지연 / 즉시 로딩N+1 관련 → Prisma, JPA, TypeORM, SQLAlchemy의 성능 차이와 올바른 사용법★★
Connection Reuse / Keep-Alive / Pooling연결 재사용 / 풀링커넥션 풀 → DB 연결 지연을 없애는 HikariCP 설정과 대기 성능 튜닝★★

핵심: 세션을 로컬에 두면 인스턴스 확장 시 풀립니다 → Redis 등으로 외부화하면 무상태·수평확장이 됩니다(12-Factor App·Tomcat 세션 클러스터링과 Redis 세션 외부화). 연결 풀링·Keep-Alive는 매 요청 연결 비용을 줄입니다(DB 연결 지연을 없애는 HikariCP 설정과 대기 성능 튜닝).

성능 지표 · 테스트

성능 병목 진단 — 캐시·세션·커넥션풀·DB·GC 구간별 병목과 TPS 천장확대

위 그림처럼 성능 개선은 "가장 바쁜 곳"이 아니라 트레이스로 특정한 "가장 느린 구간(병목)"을 푸는 것입니다. TPS가 특정 값에서 천장을 치면 커넥션 풀·스레드 풀·CPU 한계를 의심하고, Spike Test로 이벤트 급증을 사전에 검증합니다.

💡개념

얼마나 빠르고 얼마나 견디나

용어한 줄 뜻비고중요도
Bottleneck병목(가장 느린 구간)전체 속도를 지배★★★
Throughput / Latency / TPS / QPS처리량 / 지연 / 초당 트랜잭션·쿼리용어사전★★
Timeout시간 제한슬로우 동반★★
Load / Stress / Spike Test부하 / 한계 / 급증 테스트출시 전 검증(테스트 전략)★★
Benchmark성능 기준 측정비교 기준★★

핵심: 성능 개선은 '가장 바쁜 곳'이 아니라 병목(가장 느린 구간) 을 푸는 것입니다(칸반 vs 스크럼 vs 워터폴의 흐름 원리와 동일). 이벤트·세일 전엔 Spike Test로 급증을 견디는지 미리 검증합니다.

성능 병목 진단 — 직접 확인

1캐시 히트율·세션·병목으로 성능 문제 좁히기

성능 저하는 캐시·세션·병목 세 축으로 좁힙니다.

TEXT
1) 캐시 히트율: 낮으면(예: 20%) DB가 부하 → 캐시 키/TTL/용량 점검
2) 세션 위치: 로컬이면 scale-out 시 로그인 풀림 → 외부화([[twelve-factor-app]])
3) 병목: 트레이스로 가장 느린 구간 특정([[glossary-observability]])
   - DB(슬로우쿼리/N+1)? 외부 동기호출? GC? 커넥션 풀 고갈?
OUTPUT
캐시 히트율 22% → 캐시 키가 사용자별로 너무 잘게 나뉨, 재설계
세션: 톰캣 로컬 → 인스턴스 3개로 늘리자 로그인 풀림 → Redis 세션화
병목 트레이스: DB 조회 80% 점유, N+1 패턴 → eager loading([[orm-basics]])
TPS 한계 1200 → 커넥션 풀(10) 고갈이 천장([[connection-pooling]])
echo '히트율 + 세션위치 + 병목구간 점검'
🔍실행 후 확인할 것
  • 캐시 히트율이 낮으면(50% 미만) 캐시 효과 미미 → 키 설계(너무 잘게 나뉨)·TTL(너무 짧음)·용량(잦은 eviction) 점검. 무엇을 캐시할지 재검토
  • 인스턴스 늘렸는데 로그인 풀리면 세션이 로컬에 있는 것 → Redis 등으로 외부화 전엔 scale-out이 무의미(12-Factor App)
  • 병목은 "가장 바쁜 곳"이 아니라 "가장 느린 구간" — 트레이스로 특정(용어사전). DB·외부호출·GC·커넥션풀 중 무엇인지 가른다
  • TPS가 특정 값에서 천장을 치면 자원 한계(커넥션 풀·스레드 풀·CPU) 의심 → 그 한도를 늘려 다시 측정(DB 연결 지연을 없애는 HikariCP 설정과 대기 성능 튜닝)

상황: 세일 이벤트 오픈 직후 트래픽이 평소의 20배가 되자 서비스가 느려지다 멈춥니다. DB CPU가 100%, 커넥션 풀은 고갈, 응답은 타임아웃됩니다.

원인: 캐시 부재 + 풀 한계입니다. 자주 읽는 상품/재고 데이터를 캐시하지 않아 모든 요청이 DB로 직행하고, 커넥션 풀이 작아 동시 요청을 못 받아냅니다(DB 연결 지연을 없애는 HikariCP 설정과 대기 성능 튜닝). 스파이크를 견딜 설계가 없었습니다.

진단:

TEXT
□ 자주 읽는 데이터에 캐시가 있나? (히트율 측정)
□ 커넥션 풀·스레드 풀 크기가 부하 대비 적정한가?
□ Spike Test로 이 트래픽을 미리 검증했나?

해결: (1) 자주 읽고 덜 바뀌는 데이터(상품·재고)를 Cache-Aside로 캐시해 DB 부하를 덜기(캐시(Cache) 전략, 세션 스토어, Pub/Sub 실무 패턴). (2) 커넥션/스레드 풀을 부하 기준으로 재산정(DB 연결 지연을 없애는 HikariCP 설정과 대기 성능 튜닝). (3) 비핵심 작업은 비동기로 빼 큐가 스파이크를 완충(동기 vs 비동기). (4) 이벤트 전 Spike Test로 미리 검증(테스트 전략). 성능은 사고 후가 아니라 사전에 설계·측정하는 것입니다.

심화 — 히트율이 높은데도 느린 순간들

💡개념

심화: Redis 내부 동작 — 단일 스레드·빅키·핫키가 만드는 지연

히트율과 병목으로 문제를 좁히는 법을 익혔다면, 다음은 히트율이 높은데도 느려지는 경우입니다. 이때 원인은 대개 캐시 바깥이 아니라 캐시 내부 동작에 있습니다.

  • Redis는 명령을 한 줄로 처리합니다: Redis는 명령 실행이 단일 스레드라, 오래 걸리는 명령 하나가 뒤의 모든 명령을 줄 세웁니다. 수십만 키를 한 번에 훑는 KEYS, 거대한 컬렉션을 통째로 읽는 명령이 대표적입니다 — 그 몇백 ms 동안은 히트율 99%의 캐시도 전체 요청에 대해 멈춥니다. 운영 Redis에서 KEYS를 금지하고 조금씩 나눠 훑는 SCAN으로 대체하는 이유입니다.
  • 빅키(big key): 값 하나가 수 MB면 읽을 때마다 직렬화·네트워크 전송 비용이 크게 붙고, 지울 때(DEL)도 동기 삭제라 그 순간 전체가 막힙니다. 큰 값은 나눠 저장하고, 큰 키 삭제는 백그라운드로 처리하는 UNLINK를 씁니다.
  • 핫키(hot key): 특정 키 하나(오늘의 메인 상품 등)에 트래픽이 집중되면 클러스터로 노드를 늘려도 소용없습니다 — 한 키는 한 노드에만 살기 때문입니다. 이때는 노드 추가가 아니라, 앱 인스턴스 안의 수명 짧은 로컬 캐시로 그 키의 원격 조회 자체를 줄이거나 키를 여러 사본으로 복제해 분산합니다.
  • 평균이 아니라 p99를 봅니다: 위 현상들은 대부분 순간 스파이크라 평균 지연에는 거의 드러나지 않습니다. 요청 100건 중 99건이 1ms, 1건이 500ms면 평균은 6ms지만, 화면 하나가 캐시를 수십 번 조회하는 구조에선 거의 모든 화면이 그 느린 1건을 한 번은 밟습니다(꼬리 지연 증폭). 캐시 성능은 평균이 아니라 p99(느린 쪽 1%)로 봐야 이런 문제가 보입니다.

히트율은 캐시가 일을 하는지를, p99는 캐시가 발목을 잡는 순간을 알려줍니다 — 둘을 함께 봐야 온전한 그림입니다.

상황: 대시보드의 히트율·메모리·DB 지표는 모두 정상인데, 매시 정각 무렵 전체 API 응답시간이 일제히 수백 ms 튀어 오릅니다. 특정 API가 아니라 캐시를 쓰는 모든 API가 같은 순간 함께 느려지는 것이 특징입니다.

원인: 정각마다 도는 정산 배치가 Redis에서 KEYS 명령으로 수십만 키를 한 번에 훑고 있었습니다. Redis는 명령 실행이 단일 스레드라, 이 한 명령이 도는 몇백 ms 동안 다른 모든 조회·저장 명령이 그 뒤에 줄을 섭니다. 히트율은 멀쩡한데 전체 API가 동시에 느려진 이유입니다 — 병목이 DB도 앱도 아닌 캐시 자신이었던 것입니다.

진단: Redis의 SLOWLOG(느린 명령 기록)를 조회해 정각 무렵 수백 ms짜리 KEYS 명령을 찾습니다. 느린 명령의 실행 시각이 지연 스파이크 시각과 겹치고 명령의 출처가 배치 서버로 확인되면 확정입니다.

해결: 배치의 KEYS를 SCAN으로 바꿔 조금씩 나눠 훑게 하고, 애초에 전체 키를 훑지 않도록 배치 대상 키 목록을 별도 자료구조로 관리합니다. 재발 방지로 운영 Redis에서 KEYS 같은 위험 명령을 설정으로 비활성화하고, 평균이 아니라 p99 지연에 알림을 걸어(용어사전) 이런 순간 스파이크가 지표에 드러나게 합니다. 캐시는 빠른 저장소가 아니라, 빠르게 쓸 때만 빠른 저장소입니다.

💼
실무 맥락
현업 패턴

인프라/SRE로서 캐시·세션·성능은 확장성 설계의 핵심입니다 — 캐시 히트율·세션 외부화·커넥션 풀·병목을 모니터링하고(용어사전), 이벤트 전 부하/스파이크 테스트로 한계를 미리 압니다(테스트 전략). 깊은 실습은 Redis·성능 모듈에 있습니다. PM은 이 용어로 "느려요"를 "캐시 미적용 / 세션 로컬 / 풀 고갈 / 병목 구간"으로 구체화하고, 대형 이벤트 전 성능 검증을 일정에 넣어 '오픈 직후 마비'를 예방합니다.

다음 용어사전에서는 여러 고객사를 한 시스템에서 다루는 SaaS·멀티테넌트·권한 용어를 정리합니다.

용어 식별 실습으로 굳히기: 용어 식별 — Cache / 성능 / 세션 — 증상을 보고 캐시·성능·세션 용어를 가려내고 헷갈리는 짝을 구분합니다.

지식 확인

퀴즈 — 8문제

Q1

Cache-Aside(Lazy Loading) 패턴의 동작은?

Q2

캐시 히트율(Cache Hit Ratio)이 낮을 때의 의미는?

Q3

세션을 Redis 같은 외부 저장소로 빼는(외부화) 이유는?

Q4

부하 테스트(Load Test)와 스파이크 테스트(Spike Test)의 차이는?

Q5

캐시에 저장한 데이터가 원본이 바뀌어도 옛 값으로 응답하는 문제(stale)를 다루려면?

Q6

인기 캐시 키가 만료되는 순간 수많은 요청이 동시에 DB로 몰리는 현상(cache stampede)을 막으려면?

Q7

[심화] Redis 클러스터에서 '오늘의 메인 상품' 키 하나에 트래픽이 집중돼 해당 노드만 과부하다. 노드를 더 추가해도 해결되지 않는 이유와 올바른 대처는?

Q8

[심화] 캐시 히트율은 95%로 정상인데, 매시 정각마다 캐시를 쓰는 모든 API 응답이 일제히 수백 ms씩 튄다. 가장 유력한 원인과 확인 방법은?

0 / 8 답변

🧪 실습으로 확인하기

용어 식별 — Cache / 성능 / 세션

초급

캐시·성능·세션 현업 용어를 실제 증상·로그·대화 문구와 짝지어 식별한다. 캐시(히트/미스·TTL·무효화·스탬피드), 세션·연결(세션 외부화·스티키·풀링), 성능(병목·처리량·지연·부하 테스트) 세 묶음에서 "이 증상은 무슨 용어인가"를 스스로 가려낸다.

40📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요