원격 실행을 위한 원격 캐시 적중 디버깅

이 페이지에서는 캐시 적중률을 확인하는 방법과 원격 실행과 관련된 캐시 부적중을 조사하는 방법을 설명합니다.

이 페이지에서는 원격 실행을 성공적으로 활용하는 빌드 또는 테스트가 있고 원격 캐시를 효과적으로 활용하고 있는지 확인한다고 가정합니다.

캐시 적중률 확인 중

Bazel 실행의 표준 출력에서 프로세스를 나열한 INFO 줄을 확인합니다. 이 줄은 대략 Bazel 작업에 해당합니다. 작업이 실행된 줄의 세부정보입니다. 원격으로 실행되는 작업, 로컬 샌드박스에서 실행된 작업의 경우 linux-sandbox, 다른 실행 전략의 경우 다른 값을 나타내는 remote 라벨을 찾습니다. 원격 캐시에서 가져온 결과가 remote cache hit로 표시됩니다.

예:

INFO: 11 processes: 6 remote cache hit, 3 internal, 2 remote.

이 예시에서는 원격 캐시 적중이 6회였고, 2건의 작업은 캐시 적중이 없고 원격으로 실행되었습니다. 3개의 내부 부분은 무시해도 됩니다. 일반적으로 심볼릭 링크를 만드는 것과 같은 매우 작은 내부 작업입니다. 로컬 캐시 적중은 이 요약에 포함되지 않습니다. 프로세스가 0개(또는 예상보다 낮은 개수)면 bazel clean를 빌드/테스트 명령어로 실행합니다.

캐시 적중 문제 해결

예상한 캐시 적중률이 표시되지 않으면 다음 단계를 따르세요.

같은 빌드/테스트 명령어를 다시 실행하면 캐시 적중이 생성됩니다.

  1. 캐시를 채울 것으로 예상되는 빌드 또는 테스트를 실행합니다. 새 빌드가 특정 스택에서 처음 실행될 때는 원격 캐시 적중이 없을 것으로 예상할 수 있습니다. 원격 실행의 일환으로 작업 결과가 캐시에 저장되며, 이후 실행 시 이를 선택해야 합니다.

  2. bazel clean를 실행합니다. 이 명령어는 로컬 캐시를 정리하여 로컬 캐시 적중으로 결과를 마스킹하지 않고 원격 캐시 적중을 조사할 수 있습니다.

  3. 동일한 시스템에서 다시 조사 중인 빌드와 테스트를 실행합니다.

  4. INFO 줄에서 캐시 적중률을 확인하세요. remote cache hitinternal를 제외한 프로세스가 표시되지 않으면 캐시가 올바르게 채워지고 액세스되고 있는 것입니다. 이 경우 다음 섹션으로 건너뜁니다.

  5. 불일치가 발생할 수 있는 소스는 빌드에서 밀폐되지 않는 작업입니다. 이로 인해 두 실행 간에 작업이 서로 다른 작업 키를 받게 됩니다. 이러한 작업을 찾으려면 다음 단계를 따르세요.

    a. 문제의 빌드나 테스트를 다시 실행하여 실행 로그를 가져옵니다.

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_file=/tmp/exec1.log
    

    b. 두 실행 간의 실행 로그를 비교합니다. 두 로그 파일에서 작업이 동일한지 확인합니다. 불일치는 실행 사이에 발생한 변경의 단서를 제공합니다. 이러한 불일치를 없애려면 빌드를 업데이트하세요.

    캐싱 문제를 해결할 수 있고 반복 실행으로 모든 캐시 적중이 생성되면 다음 섹션으로 건너뜁니다.

    작업 ID는 동일하지만 캐시 적중이 없는 경우 구성에 항목이 있어 캐싱이 불가능한 것입니다. 일반적인 문제가 있는지 확인하려면 이 섹션을 계속 진행하세요.

    실행 로그를 diff할 필요가 없는 경우 사람이 읽을 수 있는 --execution_log_json_file 플래그를 대신 사용할 수 있습니다. 실행 시간이 포함되고 순서가 보장되지 않으므로 안정적인 diff에 사용할 수 없습니다.

  6. 실행 로그의 모든 작업에 cacheable가 true로 설정되어 있는지 확인합니다. 주어진 작업의 실행 로그에 cacheable가 표시되지 않으면 이 규칙의 정의에 BUILD 파일의 no-cache 태그가 포함될 수 있습니다. 가 있는지 진단합니다. 실행 로그에서 사람이 읽을 수 있는 progress_message 필드를 확인하여 작업의 출처를 파악합니다.

  7. 작업이 같고 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_cachedfalse이면 명령줄 또는 bazelrc 파일에서 false로 설정된 위치를 확인합니다.

머신 간 캐싱 보장

같은 컴퓨터에서 캐시 적중이 정상적으로 발생한 후 다른 머신에서 동일한 빌드/테스트를 실행합니다. 머신 간에 캐싱이 발생하지 않는다고 생각되는 경우 다음 단계를 따르세요.

  1. 빌드를 약간 수정하여 기존 캐시에 도달하지 않도록 합니다.

  2. 첫 번째 머신에서 빌드를 실행합니다.

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec1.log
    
  3. 두 번째 머신에서 빌드를 실행하여 1단계의 수정이 포함되어 있는지 확인합니다.

     bazel clean
     bazel ... build ... --execution_log_binary_file=/tmp/exec2.log
    
  4. 두 실행의 실행 로그를 비교합니다. 로그가 동일하지 않으면 빌드 구성의 불일치와 호스트 환경의 빌드 중 하나에 누수가 있는 속성이 있는지 조사합니다.

실행 로그 비교

실행 로그에는 빌드 중에 실행된 모든 작업의 레코드가 포함됩니다. 각 작업에는 작업 키의 모든 정보가 포함된 SpawnExec 요소가 있습니다. 따라서 로그가 동일하다면 작업 캐시도 마찬가지입니다. 키

캐시 적중을 예상대로 공유하지 않는 두 빌드의 로그를 비교하려면 다음 단계를 따르세요.

  1. 각 빌드에서 실행 로그를 가져와서 /tmp/exec1.log/tmp/exec2.log로 저장합니다.

  2. Bazel 소스 코드를 다운로드하고 아래 명령어를 사용하여 Bazel 폴더로 이동합니다. execlog 파서로 실행 로그를 파싱하려면 소스 코드가 필요합니다.

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. 실행 로그 파서를 사용하여 로그를 텍스트로 변환합니다. 다음 호출은 첫 번째 로그의 작업 순서와 일치하도록 두 번째 로그의 작업을 정렬해 비교하기도 쉽습니다.

    bazel build 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
    
  4. 좋아하는 텍스트를 차이점과 다르게 사용하세요./tmp/exec1.log.txt/tmp/exec2.log.txt 가 있는지 진단합니다.