이 페이지에서는 캐시 적중률을 확인하는 방법과 원격 실행 컨텍스트에서 캐시 누락을 조사하는 방법을 설명합니다.
이 페이지에서는 원격 실행을 성공적으로 활용하는 빌드 또는 테스트가 있고 원격 캐시를 효과적으로 활용하고자 한다고 가정합니다.
캐시 적중률 확인
Bazel 실행의 표준 출력에서 프로세스를 나열하는 INFO
행을 확인합니다. 이 행은 대략 Bazel 작업에 해당합니다. 이 줄에는 작업이 실행된 위치가 자세히 나와 있습니다. 원격으로 실행된 작업을 나타내는 remote
라벨, 로컬 샌드박스에서 실행된 작업의 경우 linux-sandbox
, 기타 실행 전략의 경우 다른 값을 찾습니다. 결과가 원격 캐시에서 가져온 작업은 remote cache hit
로 표시됩니다.
예를 들면 다음과 같습니다.
INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.
이 예에서는 원격 캐시 조회가 6회 있었고 2개의 작업에는 캐시 조회가 없어 원격으로 실행되었습니다. 내부 3부분은 무시할 수 있습니다.
일반적으로 심볼릭 링크 만들기와 같은 작은 내부 작업입니다. 이 요약에는 로컬 캐시 히트가 포함되지 않습니다. 프로세스가 0개이거나 예상보다 적은 경우 bazel clean
를 실행한 다음 빌드/테스트 명령어를 실행합니다.
캐시 적중 문제 해결
예상한 캐시 적중률을 얻지 못하는 경우 다음을 실행합니다.
동일한 빌드/테스트 명령어를 다시 실행하면 캐시 히트가 발생하는지 확인
캐시를 채울 것으로 예상되는 빌드 또는 테스트를 실행합니다. 특정 스택에서 새 빌드가 처음 실행되면 원격 캐시 히트가 없을 수 있습니다. 원격 실행의 일환으로 작업 결과가 캐시에 저장되며 후속 실행에서 이를 가져와야 합니다.
bazel clean
을 실행합니다. 이 명령어는 로컬 캐시를 지우므로 로컬 캐시에서 데이터를 읽지 않고도 원격 캐시 적중을 조사할 수 있습니다.조사하려는 빌드 및 테스트를 동일한 머신에서 다시 실행합니다.
캐시 적중률의
INFO
선을 확인합니다.remote cache hit
및internal
를 제외한 프로세스가 표시되지 않으면 캐시가 올바르게 채워지고 액세스되고 있는 것입니다. 이 경우 다음 섹션으로 건너뜁니다.불일치의 원인은 빌드에서 밀폐되지 않아 두 실행에서 작업이 서로 다른 작업 키를 수신하게 되는 것입니다. 이러한 작업을 찾으려면 다음 단계를 따르세요.
a. 문제의 빌드 또는 테스트를 다시 실행하여 실행 로그를 가져옵니다.
bazel clean
bazel --optional-flags build //your:target --execution_log_compact_file=/tmp/exec1.log
b. 두 실행 간의 실행 로그를 비교합니다. 두 로그 파일에서 액션이 동일한지 확인합니다. 불일치는 실행 간에 발생한 변경사항에 관한 단서를 제공합니다. 이러한 불일치를 없애도록 빌드를 업데이트합니다.
캐싱 문제를 해결할 수 있고 반복 실행 시 모든 캐시 히트가 발생하면 다음 섹션으로 건너뜁니다.
작업 ID가 동일하지만 캐시 조회가 없는 경우 구성에 캐싱을 방해하는 요소가 있는 것입니다. 이 섹션을 계속 진행하여 일반적인 문제를 확인합니다.
실행 로그의 모든 작업에
cacheable
가 true로 설정되어 있는지 확인합니다. 특정 작업의 실행 로그에cacheable
가 표시되지 않으면 해당 규칙의BUILD
파일 정의에no-cache
태그가 있을 수 있습니다. 실행 로그에서mnemonic
및target_label
필드를 확인하여 작업의 출처를 파악합니다.작업이 동일하고
cacheable
이지만 캐시가 히트하지 않는 경우 명령줄에 빌드의 캐시 조회를 사용 중지하는--noremote_accept_cached
가 포함되어 있을 수 있습니다.실제 명령줄을 파악하기 어렵다면 다음과 같이 빌드 이벤트 프로토콜의 정규 명령줄을 사용하세요.
a. 텍스트의 로그 버전을 얻으려면 Bazel 명령어에
--build_event_text_file=/tmp/bep.txt
를 추가하세요.b. 텍스트 버전의 로그를 열고
command_line_label: "canonical"
가 포함된structured_command_line
메시지를 검색합니다. 펼치면 모든 옵션이 표시됩니다.c.
remote_accept_cached
를 검색하고false
로 설정되어 있는지 확인합니다.d.
remote_accept_cached
가false
인 경우 명령줄 또는 bazelrc 파일 중 어디에서false
로 설정되는지 확인합니다.
여러 머신에서 캐싱 확인
동일한 머신에서 예상대로 캐시가 발생하면 다른 머신에서 동일한 빌드/테스트를 실행합니다. 여러 머신에서 캐싱이 이루어지지 않는 것으로 의심되면 다음 단계를 따르세요.
기존 캐시를 사용하지 않도록 빌드를 약간 수정합니다.
첫 번째 머신에서 빌드를 실행합니다.
bazel clean
bazel ... build ... --execution_log_compact_file=/tmp/exec1.log
두 번째 머신에서 빌드를 실행하여 1단계의 수정사항이 포함되었는지 확인합니다.
bazel clean
bazel ... build ... --execution_log_compact_file=/tmp/exec2.log
두 실행의 실행 로그를 비교합니다. 로그가 동일하지 않으면 빌드 구성에서 불일치가 있는지, 그리고 호스트 환경의 속성이 빌드 중 하나로 유출되는지 조사합니다.
실행 로그 비교
실행 로그에는 빌드 중에 실행된 작업의 기록이 포함됩니다. 각 레코드는 입력 (파일뿐만 아니라 명령줄 인수, 환경 변수 등)과 작업의 출력을 모두 설명합니다. 따라서 로그를 검사하면 작업이 다시 실행된 이유를 알 수 있습니다.
실행 로그는 컴팩트 (--execution_log_compact_file
), 바이너리 (--execution_log_binary_file
) 또는 JSON (--execution_log_json_file
) 형식 중 하나로 생성할 수 있습니다. 컴팩트 형식은 런타임 오버헤드가 거의 없이 훨씬 더 작은 파일을 생성하므로 권장됩니다. 다음 안내는 모든 형식에 적용됩니다. //src/tools/execlog:converter
도구를 사용하여 두 형식 간에 변환할 수도 있습니다.
예상대로 캐시 히트를 공유하지 않는 두 빌드의 로그를 비교하려면 다음 단계를 따르세요.
각 빌드에서 실행 로그를 가져와
/tmp/exec1.log
및/tmp/exec2.log
로 저장합니다.Bazel 소스 코드를 다운로드하고
//src/tools/execlog:parser
도구를 빌드합니다.git clone https://github.com/bazelbuild/bazel.git cd bazel bazel build //src/tools/execlog:parser
//src/tools/execlog:parser
도구를 사용하여 로그를 사람이 읽을 수 있는 텍스트 형식으로 변환합니다. 이 형식에서는 두 번째 로그의 작업이 첫 번째 로그의 순서와 일치하도록 정렬되므로 비교가 더 쉬워집니다.bazel-bin/src/tools/execlog/parser \ --log_path=/tmp/exec1.log \ --log_path=/tmp/exec2.log \ --output_path=/tmp/exec1.log.txt \ --output_path=/tmp/exec2.log.txt
좋아하는 텍스트 diff를 사용하여
/tmp/exec1.log.txt
와/tmp/exec2.log.txt
를 비교합니다.