왜 로컬 빌드는 한계에 부딪히는가
모노레포가 커지면 전체 빌드 그래프의 액션 수는 수만~수십만 개로 늘어난다. 개발자 노트북이나 단일 CI 러너의 코어 수는 고정되어 있으므로, 병렬화 이득은 코어 수에서 포화한다. 그 결과 클린 빌드는 수십 분이 걸리고, 캐시가 깨진 CI에서는 파이프라인 전체가 병목이 된다. 문제의 본질은 "연산량이 한 대의 처리 능력을 초과한다"는 점이다. 이걸 코어를 더 꽂는 수직 확장으로 풀면 비용 대비 효율이 급격히 나빠진다.
RBE의 기본 아이디어
원격 빌드 실행(Remote Build Execution, RBE)은 개별 빌드 액션(컴파일, 링크, 테스트)을 네트워크 너머의 워커 풀로 분산한다. Bazel·Buck2 같은 도구가 사용하는 Remote Execution API 표준은 세 가지 서비스로 구성된다: 콘텐츠 주소 저장소(CAS), 액션 캐시(AC), 그리고 실행(Execution) 서비스. 클라이언트는 각 액션의 입력 파일 해시와 커맨드를 묶어 다이제스트를 만들고, 이 다이제스트로 캐시를 조회한 뒤 미스일 때만 원격 워커에 실행을 요청한다.
핵심 전제: 해석성(hermeticity)
RBE가 성립하려면 액션이 완전히 재현 가능해야 한다. 즉 선언된 입력, 툴체인, 환경 변수만으로 출력이 결정되어야 한다. 숨은 입력(시스템 헤더, 절대 경로, 시간, 네트워크 접근)이 있으면 캐시 히트가 잘못된 결과를 재사용하거나, 워커별로 결과가 달라진다. 그래서 툴체인을 명시적으로 등록하는 것이 첫 단계다.
# .bazelrc
build --remote_executor=grpcs://rbe.example.internal:443
build --remote_cache=grpcs://rbe.example.internal:443
build --remote_instance_name=projects/main/instances/default
# 원격 워커의 실행 플랫폼(컨테이너 이미지)을 고정
build --extra_execution_platforms=//platforms:linux_x86_64
build --host_platform=//platforms:linux_x86_64
# 워커에서 실행하되 결과는 로컬로 다운로드하지 않음(BwoB)
build --remote_download_minimal
build --jobs=200
실행 플랫폼과 컨테이너 고정
--remote_download_minimal은 중간 산출물을 로컬로 내려받지 않아 네트워크 비용을 크게 줄인다. 워커가 어떤 환경에서 액션을 돌릴지는 플랫폼 정의의 exec_properties로 지정한다. 이미지 다이제스트를 태그가 아니라 sha256으로 고정해야 워커 간 재현성이 보장된다.
platform(
name = "linux_x86_64",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
exec_properties = {
"container-image": "docker://registry.internal/rbe-toolchain@sha256:abc123...",
"OSFamily": "Linux",
"dockerNetwork": "off", # 네트워크 차단으로 비해석성 유발 요소 제거
},
)
로컬·원격·캐시 전략 비교
| 모드 | 병렬도 | 캐시 공유 | 적합한 상황 |
|---|---|---|---|
| 로컬 빌드 | 코어 수 제한 | 없음(개인) | 소규모 반복 개발 |
| 원격 캐시만 | 로컬 코어 | 팀 공유 | 재빌드 절감이 목표일 때 |
| 원격 실행(RBE) | 워커 풀 규모 | 팀 공유 | 클린 빌드가 자주 발생하는 CI |
운영 시 주의점
첫째, 캐시 오염을 경계한다. 비해석적 액션이 캐시에 들어가면 전체 팀이 오염된 결과를 공유하므로, 초기에는 --remote_upload_local_results=false로 CI만 업로드하게 제한하는 편이 안전하다. 둘째, 작은 액션을 대량으로 원격 전송하면 gRPC 왕복 지연이 실행 시간을 압도한다. 액션 단위가 지나치게 잘게 쪼개졌다면 배칭이나 로컬 실행 병행이 낫다. 셋째, CAS는 지속적으로 커지므로 TTL 기반 가비지 컬렉션과 용량 모니터링이 필수다. 넷째, 워커 풀은 오토스케일해도 콜드 스타트가 있으므로 최소 대수를 유지해 피크 지연을 흡수한다.
도입 순서 제안
처음부터 원격 실행을 켜기보다, 원격 캐시만 먼저 붙여 팀 간 재빌드 절감 효과와 해석성 문제를 드러내는 것이 실전적이다. 캐시 히트율이 안정되고 비해석적 액션이 정리되면 그때 실행 서비스를 활성화한다. 측정 지표로는 캐시 히트율, 원격/로컬 액션 비율, 액션당 평균 지연을 대시보드로 추적한다. 이 세 지표가 RBE의 실제 이득과 병목을 가장 정직하게 보여준다.