Como depurar ocorrências em cache remoto para execução remota

Informar um problema Ver código-fonte Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Nesta página, descrevemos como verificar a taxa de ocorrência em cache e como investigar ausências no cache no contexto de execução remota.

Esta página pressupõe que você tenha um build e/ou teste que utilize a execução remota e que você queira garantir que está usando o cache remoto.

Como verificar a taxa de ocorrência em cache

Na saída padrão da execução do Bazel, observe a linha INFO que lista processos, que correspondem aproximadamente às ações do Bazel. Essa linha detalha onde a ação foi executada. Procure o rótulo remote, que indica uma ação executada remotamente, linux-sandbox para ações executadas em um sandbox local e outros valores para outras estratégias de execução. Uma ação com resultado proveniente de um cache remoto é exibida como remote cache hit.

Exemplo:

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

Neste exemplo, houve seis hits de cache remoto e duas ações não tiveram hits de cache e foram executadas remotamente. A parte interna 3 pode ser ignorada. Geralmente, são ações internas pequenas, como a criação de links simbólicos. As ocorrências de cache local não estão incluídas neste resumo. Se você receber 0 processos (ou um número menor do que o esperado), execute bazel clean seguido pelo comando de build/teste.

Solução de problemas de ocorrências em cache

Se você não estiver recebendo a taxa de ocorrência em cache esperada, faça o seguinte:

Garantir que a nova execução do mesmo comando de build/teste produza acertos de cache

  1. Execute as compilações e/ou os testes que você espera que preencham o cache. Na primeira vez que um novo build é executado em uma pilha específica, não há acertos de cache remoto. Como parte da execução remota, os resultados da ação são armazenados no cache, e uma execução subsequente precisa coletá-los.

  2. Execute bazel clean. Esse comando limpa o cache local, o que permite investigar ocorrências de cache remoto sem que os resultados sejam mascarados por ocorrências de cache local.

  3. Execute os builds e testes que você está investigando novamente (na mesma máquina).

  4. Verifique a linha INFO para conferir a taxa de ocorrência em cache. Se não houver nenhum processo, exceto remote cache hit e internal, o cache está sendo preenchido e acessado corretamente. Nesse caso, pule para a próxima seção.

  5. Uma possível fonte de discrepância é algo não hermético no build que faz com que as ações recebam chaves de ação diferentes nas duas execuções. Para encontrar essas ações, faça o seguinte:

    a. Execute novamente os builds ou testes em questão para acessar os registros de execução:

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

    b. Compare os registros de execução entre as duas execuções. Verifique se as ações são idênticas nos dois arquivos de registro. As discrepâncias fornecem uma pista sobre as mudanças que ocorreram entre as execuções. Atualize o build para eliminar essas discrepâncias.

    Se você conseguir resolver os problemas de armazenamento em cache e a execução repetida produzir todas as correspondências de cache, pule para a próxima seção.

    Se os IDs de ação forem idênticos, mas não houver correspondências de cache, algo na configuração está impedindo o armazenamento em cache. Continue com esta seção para verificar se há problemas comuns.

  6. Verifique se todas as ações no registro de execução têm cacheable definido como verdadeiro. Se cacheable não aparecer no registro de execução de uma determinada ação, isso significa que a regra correspondente pode ter uma tag no-cache na definição no arquivo BUILD. Analise os campos mnemonic e target_label no registro de execução para determinar de onde a ação está vendo.

  7. Se as ações forem idênticas e cacheable, mas não houver acertos de cache, é possível que a linha de comando inclua --noremote_accept_cached, o que desativaria as pesquisas de cache para um build.

    Se for difícil descobrir a linha de comando real, use a linha de comando canônica do Build Event Protocol da seguinte maneira:

    a. Adicione --build_event_text_file=/tmp/bep.txt ao seu comando Bazel para receber a versão em texto do registro.

    b. Abra a versão em texto do registro e procure a mensagem structured_command_line com command_line_label: "canonical". Ele vai listar todas as opções após a expansão.

    c. Pesquise remote_accept_cached e verifique se ele está definido como false.

    d. Se remote_accept_cached for false, determine onde ele está sendo definido como false: na linha de comando ou em um arquivo bazelrc.

Garanta o armazenamento em cache entre as máquinas

Depois que as correspondências de cache estiverem acontecendo conforme o esperado na mesma máquina, execute os mesmos builds/testes em uma máquina diferente. Se você suspeitar que o armazenamento em cache não está acontecendo em todas as máquinas, faça o seguinte:

  1. Faça uma pequena modificação no build para evitar o uso de caches atuais.

  2. Execute o build na primeira máquina:

     bazel clean
     bazel ... build ... --execution_log_compact_file=/tmp/exec1.log
    
  3. Execute o build na segunda máquina, garantindo que a modificação da etapa 1 seja incluída:

     bazel clean
     bazel ... build ... --execution_log_compact_file=/tmp/exec2.log
    
  4. Compare os registros de execução das duas execuções. Se os registros não forem idênticos, investigue as configurações de build para verificar se há discrepâncias e se as propriedades do ambiente do host estão vazando em um dos builds.

Comparar os registros de execução

O registro de execução contém registros de ações executadas durante o build. Cada registro descreve as entradas (não apenas arquivos, mas também argumentos de linha de comando, variáveis de ambiente etc.) e as saídas da ação. Assim, o exame do registro pode revelar por que uma ação foi reexecutada.

O registro de execução pode ser produzido em um dos três formatos: compacto (--execution_log_compact_file), binário (--execution_log_binary_file) ou JSON (--execution_log_json_file). O formato compacto é recomendado, porque produz arquivos muito menores com uma sobrecarga de execução muito pequena. As instruções a seguir funcionam para qualquer formato. Também é possível converter entre eles usando a ferramenta //src/tools/execlog:converter.

Para comparar os registros de dois builds que não estão compartilhando acertos de cache como esperado, faça o seguinte:

  1. Receba os registros de execução de cada build e os armazene como /tmp/exec1.log e /tmp/exec2.log.

  2. Faça o download do código-fonte do Bazel e crie a ferramenta //src/tools/execlog:parser:

    git clone https://github.com/bazelbuild/bazel.git cd bazel build //src/tools/execlog:parser

  3. Use a ferramenta //src/tools/execlog:parser para converter os registros em um formato de texto legível por humanos. Nesse formato, as ações no segundo registro são ordenadas para corresponder à ordem no primeiro registro, facilitando a comparação.

    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. Use seu texto favorito para diferenciar /tmp/exec1.log.txt e /tmp/exec2.log.txt.