이 페이지에서는 캐시 적중률을 확인하는 방법과 원격 실행 컨텍스트에서 캐시 누락을 조사하는 방법을 설명합니다.
이 페이지에서는 원격 실행을 성공적으로 활용하는 빌드 또는 테스트가 있으며 원격 캐시를 효과적으로 활용하고 싶다고 가정합니다.
캐시 적중률 확인
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
을 제외한 프로세스가 표시되지 않으면 캐시가 올바르게 채워지고 액세스되는 것입니다. 이 경우 다음 섹션으로 건너뜁니다.불일치의 가능성이 높은 원인은 빌드에 hermetic하지 않은 요소가 있어 두 실행에서 작업이 서로 다른 작업 키를 수신하기 때문입니다. 이러한 작업을 찾으려면 다음 단계를 따르세요.
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
두 실행의 실행 로그를 비교합니다. 로그가 동일하지 않으면 빌드 구성에 불일치가 있는지, 호스트 환경의 속성이 빌드 중 하나로 누출되는지 조사합니다.
실행 로그 비교
실행 로그에는 빌드 중에 실행된 작업의 기록이 포함됩니다. 각 레코드는 작업의 입력 (파일뿐만 아니라 명령줄 인수, 환경 변수 등)과 출력을 모두 설명합니다. 따라서 로그를 검사하면 작업이 다시 실행된 이유를 알 수 있습니다.
실행 로그는 3가지 형식(압축(--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
좋아하는 텍스트 차이점을 사용하여
/tmp/exec1.log.txt
과/tmp/exec2.log.txt
의 차이점을 확인합니다.