동적 실행

문제 신고하기 소스 보기

동적 실행은 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 니모닉의 기본값만 재정의됩니다. 원격 버전도 동일한 방식으로 작동합니다. 두 플래그 모두 여러 번 지정할 수 있습니다. 작업을 로컬에서 실행할 수 없으면 정상적으로 원격으로 원격으로 실행되며, 그 반대의 경우도 마찬가지입니다.

원격 시스템에 캐시가 있는 경우 --local_execution_delay 플래그는 원격 시스템이 캐시 적중을 표시한 후 로컬 실행에 지연 시간(밀리초)을 추가합니다. 이렇게 하면 캐시 적중이 많을 가능성이 있을 때 로컬 실행이 방지됩니다. 기본값은 1, 000밀리초이지만 캐시 적중에 일반적으로 걸리는 시간보다 조금 더 짧게 조정해야 합니다. 실제 시간은 원격 시스템과 왕복 소요 시간에 따라 다릅니다. 사용자 중 일부가 왕복 지연 시간을 추가할 만큼 충분히 멀지 않은 한 일반적으로 값은 지정된 원격 시스템의 모든 사용자에게 동일합니다. Bazel 프로파일링 기능을 사용하면 일반적인 캐시 적중에 걸리는 시간을 확인할 수 있습니다.

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

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

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

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

동적 실행은 언제 사용해야 하나요?

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

모든 유형의 작업이 원격 실행에 적합한 것은 아닙니다. 최상의 후보는 영구 작업자를 사용하는 등 기본적으로 로컬에서 속도가 빠른 작업이나 원격 실행의 오버헤드가 실행 시간을 지배할 만큼 빠르게 실행되는 작업입니다. 로컬에서 실행된 각 작업은 CPU 및 메모리 리소스의 일정량을 잠그므로 이러한 카테고리에 속하지 않는 작업 실행은 작업을 실행하는 작업의 실행을 지연시킬 뿐입니다.

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

동적 실행 성능이 낮은 데이터 프로파일링

Javac 작업자 8개를 사용하는 위의 프로필에서 많은 Javac 작업자가 경합에서 밀려 async-worker-finish 스레드에서 작업을 완료하는 것을 확인할 수 있습니다. 이 문제는 비작업자 니모닉이 작업자를 지연시키기에 충분한 리소스를 차지했기 때문에 발생했습니다.

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

Javac만 동적 실행으로 실행되는 경우 시작된 작업자의 약 절반만이 작업을 시작한 후 레이스에서 지게 됩니다.

이전에 권장되는 --experimental_spawn_scheduler 플래그는 지원 중단되었습니다. 동적 실행을 켜고 dynamic을 모든 니모닉의 기본 전략으로 설정하므로 종종 이러한 문제가 발생할 수 있습니다.

문제 해결

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

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