반복 속도 최적화

문제 신고 소스 보기

이 페이지에서는 Bazel을 반복적으로 실행할 때 Bazel의 빌드 성능을 최적화하는 방법을 설명합니다.

Bazel의 런타임 상태

Bazel 호출에는 상호 작용하는 여러 부분이 포함됩니다.

  • bazel 명령줄 인터페이스 (CLI)는 사용자 대상 프런트엔드 도구로, 사용자로부터 명령어를 수신합니다.

  • CLI 도구는 고유한 출력 베이스마다 Bazel 서버를 시작합니다. Bazel 서버는 일반적으로 영구적이지만, 리소스를 낭비하지 않도록 유휴 시간 후 종료됩니다.

  • Bazel 서버는 지정된 명령어(build, run, cquery 등)의 로드 및 분석 단계를 수행하여 메모리에 빌드 그래프의 필요한 부분을 구성합니다. 결과 데이터 구조는 분석 캐시의 일부로 Bazel 서버에 보관됩니다.

  • Bazel 서버는 작업 실행을 수행할 수도 있고 원격 실행을 위해 작업을 전송할 수도 있습니다(설정된 경우). 작업 실행 결과도 작업 캐시(또는 실행 캐시. 로컬 또는 원격일 수 있으며 Bazel 서버 간에 공유될 수 있음)에 캐시됩니다.

  • Bazel 호출의 결과가 출력 트리에서 제공됩니다.

Bazel을 반복적으로 실행

일반적인 개발자 워크플로에서는 코드를 반복적으로 빌드 (또는 실행)하는 것이 일반적이며, 종종 매우 높은 빈도로 (예: 일부 컴파일 오류를 해결하거나 실패 테스트를 조사하는 경우)됩니다. 이 상황에서 bazel의 반복되는 호출은 반복되는 기본 작업 (예: 컴파일러 호출 또는 테스트 실행)에 비해 오버헤드가 최대한 적은 것이 중요합니다.

이 점을 고려하여 Bazel의 런타임 상태를 다시 살펴보겠습니다.

분석 캐시는 중요한 데이터입니다. 콜드 런의 로드 및 분석 단계 (예: Bazel 서버가 시작된 직후의 실행 또는 분석 캐시가 삭제된 시점)에만 상당한 시간이 소요될 수 있습니다. 성공적인 단일 콜드 빌드의 경우 (예: 프로덕션 출시의 경우) 이 비용은 감당할 수 있지만 동일한 타겟을 반복적으로 빌드하는 경우 이 비용은 각 호출마다 분할 상환되고 반복되지 않는 것이 중요합니다.

분석 캐시는 다소 휘발성이 있습니다. 우선, Bazel 서버의 진행 중인 상태에 속하므로 서버를 잃으면 캐시가 손실됩니다. 하지만 캐시는 매우 쉽게 무효화됩니다. 예를 들어 bazel 명령줄 플래그로 인해 캐시가 삭제됩니다. 그 이유는 많은 플래그가 빌드 그래프에 영향을 미치기 때문입니다 (예: 구성 가능한 속성으로 인해). 일부 플래그 변경으로 인해 Bazel 서버가 다시 시작될 수도 있습니다 (예: 시작 옵션 변경).

좋은 실행 캐시는 빌드 성능에도 중요합니다. 실행 캐시는 디스크에 로컬로 또는 원격으로 보관할 수 있습니다. 캐시는 Bazel 서버 간에, 그리고 실제로 개발자 간에 공유될 수 있습니다.

분석 캐시 삭제 방지

Bazel은 분석 캐시가 삭제되었거나 서버가 다시 시작되면 경고를 출력합니다. 다음 중 하나를 반복적으로 사용하는 경우 피해야 합니다.

  • 반복적인 워크플로 도중에 bazel 플래그를 변경하는 것에 유의하세요. 예를 들어 bazel build -c optbazel cquery를 함께 사용하면 각 명령어가 서로의 분석 캐시를 삭제합니다. 일반적으로 특정 워크플로의 기간에 고정된 플래그 집합을 사용하는 것이 좋습니다.

  • Bazel 서버가 손실되면 분석 캐시도 사라집니다. Bazel 서버는 구성 가능한 유휴 시간을 가지며, 그 후에는 종료됩니다. 이 시간은 bazelrc 파일을 통해 필요에 맞게 구성할 수 있습니다. 또한 시작 플래그가 변경될 때 서버가 다시 시작되었으므로 가능하면 이러한 플래그를 변경하지 마세요.

  • Bazel이 실행되는 동안 Ctrl-C를 반복해서 누르면 Bazel 서버가 종료된다는 주의가 있습니다. 더 이상 필요하지 않은 실행 중인 빌드를 중단하여 시간을 절약하고 싶은 유혹이 들겠지만, Ctrl-C를 한 번만 눌러 현재 호출의 적절한 종료를 요청합니다.

  • 동일한 작업공간에서 여러 플래그 집합을 사용하려면 --output_base 플래그로 전환된 여러 개의 고유한 출력 베이스를 사용하면 됩니다. 각 출력 베이스에는 자체 Bazel 서버가 있습니다.

이 조건을 경고가 아닌 오류로 만들려면 Bazel 6.4.0에서 도입된 --noallow_analysis_cache_discard 플래그를 사용하면 됩니다.