2 min read

CI 캐시 최적화 플레이북

의존성 캐시, 빌드 아티팩트 캐시를 분리해 파이프라인 시간을 단축하는 방법

CI 캐시 최적화 플레이북 thumbnail

도입

CI 시간이 길어지면 개발 생산성뿐 아니라 배포 안정성도 떨어진다. 캐시를 무작정 켜면 빨라질 것 같지만 키 설계가 잘못되면 오히려 불안정한 빌드가 발생한다. 이 글은 신뢰성을 유지하면서 CI 캐시 효율을 높이는 실전 플레이북을 정리한다.

CI 캐시 최적화 플레이북 커버
Wikimedia Commons 기반 무료 이미지

문제 정의

캐시 최적화는 속도와 재현성의 균형 문제다.

  • 캐시 키 범위가 넓어 사소한 변경에도 전체 캐시가 무효화된다.
  • 의존성 캐시와 빌드 산출물 캐시를 혼합해 오염 가능성이 높다.
  • 캐시 적중률을 관측하지 않아 최적화 효과를 측정하지 못한다.

핵심은 캐시를 계층으로 나누는 것이다. 의존성, 빌드 중간 결과, 테스트 결과를 별도로 관리해야 한다.

핵심 개념

관점설계 기준검증 포인트
키 설계락파일 + 런타임 버전 포함cache miss 원인 분류
계층화deps/build/test 캐시 분리오염 재현률
관측hit ratio 대시보드평균 파이프라인 시간
정리TTL 기반 캐시 청소스토리지 비용

속도 개선은 측정 가능한 지표가 있어야 유지된다. 캐시 적중률과 실패율을 함께 추적하면 과최적화를 방지할 수 있다.

코드 예시 1: GitHub Actions 캐시 키

- name: Cache pnpm store
  uses: actions/cache@v4
  with:
    path: ~/.pnpm-store
    key: pnpm-\${{ runner.os }}-\${{ hashFiles('pnpm-lock.yaml') }}
    restore-keys: |
      pnpm-\${{ runner.os }}-

- name: Cache Next build
  uses: actions/cache@v4
  with:
    path: .next/cache
    key: next-\${{ runner.os }}-\${{ hashFiles('**/*.ts', '**/*.tsx', 'next.config.ts') }}

코드 예시 2: 캐시 지표 수집

export function logCacheMetrics(input: { step: string; hit: boolean; durationMs: number }) {
  console.log(
    JSON.stringify({
      metric: "ci_cache",
      step: input.step,
      hit: input.hit,
      duration_ms: input.durationMs,
      timestamp: new Date().toISOString(),
    }),
  );
}

아키텍처 흐름

Mermaid diagram rendering...

트레이드오프

  • 캐시 범위를 좁히면 안정성은 높지만 최대 속도 개선폭은 줄어든다.
  • restore-keys를 넓게 두면 적중률은 오르지만 오래된 캐시를 불러올 위험이 있다.
  • 캐시 계층이 늘면 설정 복잡도는 증가하지만 디버깅 난이도는 오히려 낮아진다.

정리

CI 캐시 최적화는 빠른 빌드보다 재현 가능한 빌드를 목표로 해야 한다. 계층화된 캐시 전략과 지표 기반 튜닝을 결합하면 안정성과 속도를 동시에 확보할 수 있다.

이미지 출처

  • Cover: source link
  • License: CC BY-SA 3.0 / Author: Bernard Gagnon
  • Note: Wikimedia Commons 무료 라이선스 이미지를 다운로드 후 1600px 기준 JPG로 최적화했습니다.

댓글