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

Esta página descreve como verificar a taxa de ocorrências em cache e como investigar ausências no cache no contexto da execução remota.

Esta página pressupõe que você tenha uma versão e/ou teste que utilize a execução remota e queira garantir o uso eficaz do cache remoto.

Como verificar a taxa de ocorrências em cache

Na saída padrão da execução do Bazel, procure 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 cujo resultado veio 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 ocorrências em cache remoto e duas ações não tiveram ocorrências em 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 em cache local não estão incluídas neste resumo. Se você estiver recebendo 0 processos (ou um número menor do que o esperado), execute bazel clean seguido do comando de versão/teste.

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

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

Verifique se a execução do mesmo comando de versão/teste produz ocorrências em cache

  1. Execute as versões e/ou testes que você espera preencher o cache. Na primeira vez que uma nova versão é executada em uma pilha específica, não há ocorrências em cache remoto. Como parte da execução remota, os resultados da ação são armazenados no cache e uma execução subsequente precisa buscá-los.

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

  3. Execute novamente as versões e os testes que você está investigando (na mesma máquina).

  4. Verifique a linha INFO para a taxa de ocorrências em cache. Se você não vir processos, 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 na versão 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 as versões ou testes em questão para receber 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 a versão para eliminar essas discrepâncias.

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

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

  6. Verifique se todas as ações no registro de execução têm cacheable definido como "true". 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. Consulte os campos mnemonic e target_label no registro de execução para ajudar a determinar de onde a ação está vindo

  7. Se as ações forem idênticas e cacheable, mas não houver ocorrências em cache, é possível que a linha de comando inclua --noremote_accept_cached, que desativa as pesquisas de cache para uma versão.

    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 comando do Bazel para receber a versão em texto do registro.

    b. Abra a versão em texto do registro e pesquise a structured_command_line mensagem com command_line_label: "canonical". Ela 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.

Garantir o armazenamento em cache em todas as máquinas

Depois que as ocorrências em cache acontecerem conforme o esperado na mesma máquina, execute as mesmas versões/testes em outra máquina. 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 na versão para evitar atingir caches atuais.

  2. Execute a versão na primeira máquina:

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

     bazel clean
     bazel ... build ... --execution_log_compact_file=/tmp/exec2.log
  4. Compare os registros de execução para as duas execuções. Se os registros não forem idênticos, investigue as configurações de versão em busca de discrepâncias, bem como propriedades do ambiente do host que vazam para qualquer uma das versões.

Comparar os registros de execução

O registro de execução contém registros de ações executadas durante a versão. 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 de 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 tempo de execução muito pequena. As instruções a seguir funcionam para qualquer formato. Você também pode converter entre eles usando a ferramenta //src/tools/execlog:converter.

Para comparar registros de duas versões que não estão compartilhando ocorrências em cache conforme o esperado, faça o seguinte:

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

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

    git clone https://github.com/bazelbuild/bazel.git cd bazel 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. Nesse formato, as ações no segundo registro são classificadas 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 o diferenciador de texto de sua preferência para comparar /tmp/exec1.log.txt e /tmp/exec2.log.txt.