조립 최적화 및 캐싱
(섹션: 기술 및 인프라)
간단한 요약
iGaming의 CI/CD 속도는 피크 하중에서 방출 속도, 미세한 비용 및 p99 안정성에 직접적인 영향을 미칩니다. 핵심은 올바른 캐시 (종속성, 아티팩트, 컨테이너 레이어, 중간 컴파일 결과), 증분 빌드 및 결정론입니다. "좋은" 빌드는 변경되지 않은 입력으로 빠르게 반복되며 캐시 장애는 예측 가능하고 제어 할 수 있습니다.
1) 캐시 맵 및 캐시
의존성: NPM/pnpm 패키지, 핍휠/시, Maven/Gradle, Go mods, 화물 상자, NuGet.
중간 편집 아티팩트: '~/.cash/pip', '~/.m2', '.gradle', '~/.carrey/registry/',' $ GOMODCACHE ',' taget/', 'build/',' 노드 _ 모듈/.pnpm-store '.
컨테이너 계층: Docker 계층 캐시 (BuildKit/GHA 캐시), 레지스트리 기반 캐시, 다단계.
도구 및 SDK: 툴체인/마이크로 이미지 (JDK, 노드, 파이썬, 녹음 대상).
모노/폴리 레포 메타: 작업을위한 Nx/Turborepo/Bazel 원격 캐시 (린트/테스트/빌드).
테스트 데이터 및 e2e 수정: UI 번들로 컴파일 된 데이터베이스 스냅 샷.
ML/데이터: 준비된 데이터 세트, 임베딩, 컴파일 된 엔진 (TensorRT/ONNX).
2) 빠르고 예측 가능한 어셈블리의 원리
1. 결정: 버전 수정 (잠금 파일), 핀 기본 이미지, 밀폐 플러그인 → 재현 가능한 출력.
2. 이데올로기: 동일한 어셈블리 → 동일한 인공물과 해시.
3. 증가: 변경된 것만 재구성 (DAG/요구/행렬/영향).
4. 지역성 및 "열": 레지스트리 주자/레지스트리 옆에 캐시가 있으며 봉우리 전에 예열됩니다.
5. 명시 적 장애: 잠금 파일/구성 파일 및 컨텐츠 해시로 키를 캐시합니다.
6. 위생: TTL/' 만료 _ in ', 자동 청소, 캐시 크기 제어 및 아티팩트.
7. 공급망 보안: 비밀을위한 캐시 차량 휴지통; SBOM/artifact 서명은 필수입니다.
3) Docker/OCI: 재 조립되지 않은 빠른 이미지
패턴
다단계 (빌더 → 런타임).
최소 런타임 (디스트로리스/ubi-micro, 필요한 경우/ca-certs).
계층 순서: 먼저 거의 변경하지 않고 코드를 변경합니다.
'.dockerandei': '.git', 테스트/비품, 로컬 캐시를 제외하십시오.
빌드 키트: '캐시/에서' → 작업과 지점 간의 캐시 공유.
도커 파일 예 (노드 + pnpm)
dockerfile syntax=docker/dockerfile:1.7
FROM node:20-bookworm AS deps
WORKDIR /app
COPY pnpm-lock.yaml./
RUN corepack enable && pnpm fetch
FROM node:20-bookworm AS builder
WORKDIR /app
COPY --from=deps /root/.cache/pnpm /root/.cache/pnpm
COPY package.json pnpm-lock.yaml./
RUN corepack enable && pnpm install --offline
COPY..
RUN pnpm build
FROM gcr.io/distroless/nodejs20 AS runtime
WORKDIR /app
COPY --from=builder /app/dist./dist
USER 10001
CMD ["dist/server.js"]
빌드 키트 (CI) (GitHub 동작)
yaml
- uses: docker/setup-buildx-action@v3
- uses: actions/cache@v4 with:
path: /tmp/.buildx-cache key: buildx-${{ github.ref }}-${{ github.sha }}
restore-keys: buildx-${{ github.ref }}-
- uses: docker/build-push-action@v6 with:
push: true tags: ${{ env.IMAGE }}
cache-from: type=gha cache-to: type=gha,mode=max
4) 언어 생태계: 캐시 할 내용과 방법
자바/코 틀린 (Maven/Gradle)
원격 캐시 그레이드, 동시성, 주문형 구성.
캐시 키: 해시 빌드. 그레이드 [.kts] '+ lockfiles +' 그래들 래퍼. 속성 '.
스토리지/HTTP에 캐시 노드를 게시합니다.
패키지별로 증분 컴파일 및 테스트 분할.
yaml
GitLab CI cache:
key: gradle-${CI_COMMIT_REF_SLUG}
paths: [.gradle/caches,.gradle/wrapper ]
script:
-./gradlew --build-cache --parallel build
노드. js (npm/pnpm/yarn)
로컬 상점 캐시 ('~/.npm', '~/.cash/pnpm'), 잠금 파일 키.
작업을위한 Nx/Turborepo 원격 캐시 (S3/Redis) (보푸라기/테스트/빌드).
'터보 런 빌드-캐시-dir = .turbo' 및 모노 레포의 "영향을받는" 모드.
파이썬 (pip/Poetry)
캐시 휠 + virtualenv; '요구 사항 별 핵심. 시를 잠그십시오. 잠금 '.
행렬 사이를 재사용하여 별도의 단계로 휠을 조립합니다.
C 확장- 빌더 이미지의 'pip wheel' + 'auditwheel' 의 경우.
이동
'GOMODCACHE', 'GOCACHE'; 'GOTOOLCHAIN '/버전을 수정합니다.
단계를 나눕니다: 'go mod down' → 코드 사본 → 'go build'.
큰 모노레일-Bazel/Bazelisk 또는 레이어 빌드가있는 'magage'.
녹
'~/.carrey/registry', '~/.carrey/git', 'taget/'; 스캐시 (원격/로컬).
'Cargo의 지점간에 캐시 공유. 잠금 '.
C/C + +
컴파일러 플래그 및 SDK 버전별 캐시/스캐시 + 키.
별도의 기본 이미지로 툴체인을 꺼내십시오.
5) Bazel/Nx/Turborepo: 작업 및 그래프 캐시
Bazel 리모컨 캐시 (TH/Cloud) - 컨텐츠 주소 지정 가능; 엄격한 압박감, 샌드 박스.
Nx/Turborepo-작업 출력 캐시 및 모노 레포의 "전용 영향" 실행.
장애: 단계 입력 (파일/플래그/변수) 에 따라 다릅니다.
6) 캐시 장애 전략
키 = 입력 해시: 잠금 파일, 컴파일러 구성, 표현.
가벼운 장애: '복원 키' (GHA )/접두사 (GLCI).
어려운 장애: 중요한 변화를 위해 네임 스페이스/키를 회전시킵니다.
레이어 분리: 소스 대 소스-의존성이 크지 않고 코드를 변경합니다.
7) 증분 빌드 및 행렬
DAG/요구: 종속 bs을 병렬로 실행하고 시퀀스를 기다리지 마십시오.
경로 필터-영향을받는 구성 요소에 대해서만 트리거.
샤드 테스트: 디렉토리/시드별로 지속 시간을 정렬하십시오.
따뜻한 풀 러너: 정점 전에 예열 된 이미지/캐시 (토너먼트/캠페인).
8) 아티팩트 대 캐시: 얼마나 다른가
캐시: 재사용 된 입력/중간 결과, 더러운 영역, TTL 쇼트/매체.
아티팩트: 최종 어셈블리 (이미지, 바이너리, 차트), 변경 불가능, 서명, SBOM.
규칙: 캐시는 적극적으로 청소되고 아티팩트는 릴리스 정책에 따라 저장됩니다.
9) 관찰 가능성, KPI 및 FinOps
메트릭 (파이프 라인/리포 별):- 캐시 적중률 (%), 따뜻한 시작 대 콜드 스타트 시간, 평균/중간 단계 지속 시간.
- 파이프 라인/작업 당 비용, 캐시/아티팩트 크기, 처리량 (작업/시간).
- 모노 레포에서 "영향을받는" 공유는 변경되지 않고 재건됩니다 (폐기물).
- 적중률은 임계 값 아래로 떨어지고 이미지 시간이 증가하며 아티팩트가 팽창하고 SLO가 누락됩니다.
10) 캐시 보안 및 공급망
캐시/아티팩트에 비밀이 없습니다. 마스크 바, 비밀 스캔.
핀 www외부 작업/플러그인, 신뢰할 수있는 러너 만 있습니다.
컨테이너/바이너리 (cosign), SBOM (CycloneDX/SPDX) 에 서명하고 CD를 확인하십시오.
격리: 'dev/stage/prod' 에 대한 별도의 캐시 네임 스페이스, 외국 지점에 대한 읽기 전용 권한.
11) 실제 템플릿
GitHub 동작-언어 + 컨테이너
yaml name: ci on: [push, pull_request]
concurrency: { group: ${{ github.ref }}, cancel-in-progress: true }
jobs:
build:
runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: { node-version: '20' }
- uses: actions/cache@v4 with:
path: ~/.cache/pnpm key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
- run: corepack enable && pnpm i --frozen-lockfile
- run: pnpm build
- uses: docker/build-push-action@v6 with:
tags: ${{ env.IMAGE }}
cache-from: type=gha cache-to: type=gha,mode=max
GitLab CI-그레이들 리모컨 캐시
yaml variables:
GRADLE_USER_HOME: ".gradle"
cache:
key: gradle-${CI_COMMIT_REF_SLUG}
paths: [.gradle/wrapper,.gradle/caches ]
build:
stage: build script:
-./gradlew --build-cache --no-daemon build artifacts:
paths: [ "build/libs/.jar" ]
expire_in: 3 days
젠킨스-캐시/스캐시
groovy pipeline {
agent { label 'cpp' }
environment { CCACHE_DIR = '/cache/ccache' }
stages {
stage('Build') {
steps {
sh 'ccache -M 10G'
sh 'cmake -B build -S. && cmake --build build -j$(nproc)'
}
}
}
post { always { sh 'ccache -s' } }
}
12) ML/데이터: 무거운 어셈블리 속도 향상
로컬 NVMe 러너의 모델/임베딩/데이터 세트 캐시; 해시 버전.
릴리스 아티팩트로 사전 조립 TensorRT/ONNX 엔진; 추론에서 재사용.
대형 모델의 청크 아티팩트 (분할); TTL 및 지연된 청소.
13) 구현 점검표
1. 잠금 파일 및 기본 이미지를 전송합니다. 빌드 키트 사용하기
2. 별도의 Docker 계층: deps → 코드; '.dockerandei' 를 추가하십시오.
3. 원격 캐시 올리기 (Gradle/Bazel/Nx/Turbo); 종속성 프록시를 시작합니다.
4. 잠금 파일로 CI의 종속성 캐시를 설정합니다. 행렬 및 '경로 필터' 가 포함됩니다.
5. 모노 레포에서 증분 빌드를 입력하고 "만 영향을받습니다".
6. 측정 히트 율, 따뜻한/추운 시간, 비용; 경고를 내립니다.
7. SBOM/서명 활성화하고 캐시의 비밀을 거부하십시오.
8. 피크 릴리스 전에 캐시를 예열하십시오. TTL/보존을 조절합니다.
9. 문서 캐시 장애 및 런북은 "캐시 파손" 으로 표시됩니다.
10. 정기적으로 "영원한" 캐시를 청소하고 무거운 유물을 보관하십시오.
14) 안티 패턴
키/TTL → 플레이크 및 가비지가없는 "영구" 캐시 공유
덱을 설치하기 전에 단계가 자주 변경되는 거대한 도커 파일.
아티팩트와 캐시 혼합; 서명/SBOM 없음.
압축되지 않은 도구 버전 → "캐시는 반복되지만 반복되지는 않습니다".
각 PR에서 "모두를위한" 행렬; '동시성 부족. 취소 '.
따뜻한 캐시가없고 의존성 프록시가없는 단일 러너.
결과
어셈블리 최적화는 캐시, 증분 및 결정론을 사용한 체계적인 작업입니다. 올바른 도커 파일 구조, 빌드 용 원격 캐시, 종속성 프록시 및 장애 규율은 빠르고 저렴하며 재현 가능한 파이프 라인을 제공합니다. 관찰 및 안전 규칙을 추가하면 릴리스가 빈번하고 안정적이며 경제적입니다.