날짜 비워 두기: BazelCon 2023이 10월 24~25일에 Google 뮌헨에서 열립니다. 자세히 알아보기

동적 실행

문제 신고 소스 보기

동적 실행은 Bazel 0.21부터 동일한 작업의 로컬 및 원격 실행이 병렬로 시작되어 완료된 첫 번째 브랜치의 출력을 사용하여 다른 브랜치를 취소하는 기능입니다. 원격 빌드 시스템의 실행 성능 또는 대규모 공유 캐시를 로컬 실행의 짧은 지연 시간과 결합하므로 클린 빌드와 증분 빌드 모두에 이 점이 극대화됩니다.

이 페이지에서는 동적 실행을 사용 설정, 조정, 디버그하는 방법을 설명합니다. 로컬 및 원격 실행을 모두 설정하고 성능 향상을 위해 Bazel 설정을 조정하려는 경우 이 페이지를 참조하세요. 원격 실행이 아직 설정되지 않은 경우 먼저 Bazel 원격 실행 개요로 이동합니다.

동적 실행을 사용 설정하시겠어요?

동적 실행 모듈은 Bazel의 일부이지만, 동적 실행을 사용하려면 이미 동일한 Bazel 설정에서 로컬과 원격으로 모두 컴파일할 수 있어야 합니다.

동적 실행 모듈을 사용 설정하려면 --internal_spawn_scheduler 플래그를 Bazel에 전달합니다. 그러면 dynamic라는 새로운 실행 전략이 추가됩니다. 이제 --strategy=Javac=dynamic와 같이 동적으로 실행하려는 연상 기호에 대한 전략으로 이를 사용할 수 있습니다. 동적 실행을 사용 설정할 수 있는 연상 기호 선택 방법을 알아보려면 다음 섹션을 참조하세요.

동적 전략을 사용하는 모든 연상 기호의 경우 원격 실행 전략은 --dynamic_remote_strategy 플래그에서, 로컬 전략은 --dynamic_local_strategy 플래그에서 가져옵니다. --dynamic_local_strategy=worker,sandboxed를 전달하면 동적 실행의 로컬 브랜치의 기본값이 작업자 또는 샌드박스 실행으로 시도하도록 설정됩니다. --dynamic_local_strategy=Javac=worker를 전달하면 Javac 연상 기호의 기본값만 재정의합니다. 원격 버전도 동일하게 작동합니다. 두 플래그를 모두 여러 번 지정할 수 있습니다. 로컬에서 실행할 수 없는 작업은 평소와 같이 원격으로 실행되며 그 반대도 마찬가지입니다.

원격 시스템에 캐시가 있으면 원격 플래그는 캐시 적중이 표시된 후 --dynamic_local_execution_delay 플래그가 로컬 실행에 밀리초 단위의 지연을 추가합니다. 이렇게 하면 더 많은 캐시 적중이 발생할 가능성이 있는 경우 로컬 실행이 실행되지 않습니다. 기본값은 1, 000ms이지만 일반적으로 캐시 적중에 소요되는 시간보다 조금 더 길어야 합니다. 실제 시간은 원격 시스템과 왕복 시간에 따라 다릅니다. 왕복 지연 시간을 추가하기에 충분한 거리가 없는 경우가 아니라면 일반적으로 특정 원격 시스템의 모든 사용자에게 동일한 값이 적용됩니다. Bazel 프로파일링 기능을 사용하여 일반적인 캐시 적중에 걸리는 시간을 확인할 수 있습니다.

동적 실행은 로컬 샌드박스 전략 및 영구 작업자와 함께 사용할 수 있습니다. 영구 작업자는 동적 실행과 함께 사용되면 샌드박스로 자동 실행되며 멀티플렉스 작업자는 사용할 수 없습니다. Darwin 및 Windows 시스템에서는 샌드박스 전략이 느릴 수 있습니다. --reuse_sandbox_directories를 전달하여 이러한 시스템에서 샌드박스를 생성하는 오버헤드를 줄일 수 있습니다.

동적 전략도 standalone 전략으로 실행할 수 있지만 standalone 전략은 실행 시작 시 출력 잠금을 사용해야 하므로 원격 전략이 먼저 완료되지 않도록 효과적으로 차단합니다. --experimental_local_lockfree_output 플래그는 로컬 실행이 출력에 직접 쓸 수 있도록 허용하여 이 문제를 해결할 수 있지만, 먼저 원격 실행이 완료되면 이를 취소합니다.

동적 실행 브랜치 중 하나가 먼저 완료되지만 실패할 경우 전체 작업이 실패합니다. 이는 로컬 실행과 원격 실행 간의 차이점이 무시되지 않도록 하기 위한 것입니다.

동적 실행 및 잠금 작동 방식에 관한 자세한 내용은 훌리오 메리노의 훌륭한 블로그 게시물을 참고하세요.

동적 실행을 사용해야 하는 경우

동적 실행을 위해서는 일종의 원격 실행 시스템이 필요합니다. 캐시 부적중은 실패한 작업으로 간주되므로 현재 캐시 전용 원격 시스템을 사용할 수 없습니다.

모든 유형의 작업이 원격 실행에 적합한 것은 아닙니다. 가장 좋은 후보는 본질적으로 로컬에 더 빠른 도구이며, 예를 들어 영구 작업자를 사용하거나 원격 실행의 오버헤드가 지날 만큼 충분히 빠르게 실행되는 경우가 이에 해당합니다. 로컬에서 실행되는 각 작업은 특정 CPU 및 메모리 리소스를 잠그므로 이러한 카테고리에 속하지 않는 작업은 실행 시 단순히 실행을 지연시킵니다.

5.0.0-pre.20210708.4 버전부터 성능 프로파일링에는 동적 실행 경합을 잃은 후 작업 요청을 완료하는 데 소요된 시간을 포함하여 작업자 실행에 관한 데이터가 포함됩니다. 동적 실행 작업자 스레드가 리소스를 획득하는 데 상당한 시간을 소비하거나 async-worker-finish에서 많은 시간을 보내는 경우, 로컬 스레드가 작업자 스레드를 지연시키는 것일 수 있습니다.

동적 실행 성능 저하가 있는 데이터 프로파일링

위의 프로필에서 8개의 Javac 작업자를 사용하는 경우 많은 Javac 작업자가 레이스를 잃고 async-worker-finish 스레드에서 작업을 마쳤습니다. 이는 작업자가 아닌 연상 기호로 인해 작업자를 지연시키는 데 충분한 리소스가 필요했기 때문입니다.

더 나은 동적 실행 성능으로 데이터 프로파일링

동적 실행으로 Javac만 실행하면 시작된 작업자의 약 절반만 작업을 시작한 후 경합을 잃게 됩니다.

이전에 권장된 --experimental_spawn_scheduler 플래그는 지원 중단되었습니다. 동적 실행을 사용 설정하고 dynamic를 모든 연상 기호의 기본 전략으로 설정하며, 이로 인해 종종 이러한 종류의 문제가 발생합니다.

문제 해결

동적 실행 문제는 로컬 실행과 원격 실행의 몇 가지 특정 조합에서만 나타날 수 있으므로 미묘하고 디버그하기 어려울 수 있습니다. --debug_spawn_scheduler는 이러한 문제를 디버그하는 데 도움이 될 수 있는 동적 실행 시스템의 출력을 추가로 추가합니다. 또한 --dynamic_local_execution_delay 플래그와 원격 작업 수와 로컬 작업 수를 조정하여 문제를 더 쉽게 재현할 수 있습니다.

standalone 전략을 사용하여 동적 실행에 문제가 발생하면 --experimental_local_lockfree_output 없이 실행하거나 샌드박스 처리된 로컬 작업을 실행하세요. 이로 인해 빌드가 약간 느려질 수 있지만 (Mac 또는 Windows를 사용하는 경우 위의 내용 참조) 실패할 수 있는 일부 원인이 삭제됩니다.