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

Informar um problema Acessar a origem

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

Nesta página, presumimos que você tem uma versão e/ou teste que usa com êxito a execução remota e quer garantir que está utilizando o cache remoto com êxito.

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 ocorrências em cache remoto e duas ações não tinham ocorrências em cache e foram executadas remotamente. As três partes internas podem ser ignoradas. Em geral, são pequenas ações internas, como a criação de links simbólicos. As ocorrências em cache local não estão incluídas neste resumo. Se você não estiver recebendo nenhum processo (ou um número menor do que o esperado), execute bazel clean seguido pelo comando build/test.

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:

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

  1. Execute os builds e/ou testes que você espera preencher o cache. Na primeira vez que um novo build for executado em uma pilha específica, não haverá ocorrências em cache remoto. Como parte da execução remota, os resultados da ação são armazenados no cache e capturados em uma execução subsequente.

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

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

  4. Verifique a taxa de ocorrência em cache na linha INFO. Se não encontrar processos, exceto remote cache hit e internal, isso significa que o cache está sendo preenchido e acessado corretamente. Nesse caso, pule para a próxima seção.

  5. Uma fonte provável de discrepância é algo não hermético no build, fazendo 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 os testes em questão para receber os registros de execução:

      bazel clean
      bazel --optional-flags build //your:target --execution_log_binary_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 alterações que ocorreram entre as execuções. Atualize seu build 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 sua configuração está impedindo o armazenamento em cache. Continue nesta seção para verificar 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 para uma determinada ação, isso significa que a regra correspondente pode ter uma tag no-cache na definição no arquivo BUILD. Confira os campos mnemonic e target_label no registro de execução para ajudar a determinar a origem da ação.

  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, o que desativaria as pesquisas no cache de uma versão.

    Se for difícil descobrir a linha de comando real, use a linha de comando canônica do Build Event Protocol (link em inglês) 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 pesquise a mensagem structured_command_line com command_line_label: "canonical". Ele listará todas as opções após a expansão.

    c. Pesquise remote_accept_cached e verifique se ela está definida 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 máquinas

Depois que as ocorrências em cache acontecerem como 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 entre máquinas, faça o seguinte:

  1. Faça uma pequena modificação na sua versão para evitar atingir os caches existentes.

  2. Execute o build na primeira máquina:

     bazel clean
     bazel ... build ... --execution_log_binary_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_binary_file=/tmp/exec2.log
    
  4. Compare os registros das duas execuções. Se os registros não forem idênticos, investigue se há discrepâncias nas configurações do seu build, bem como nas propriedades do ambiente do host com vazamentos em qualquer um dos builds.

Como comparar os registros de execução

Os registros de execução contêm registros de todas as ações executadas durante o build. Para cada ação, há um elemento SpawnExec que contém todas as informações da chave de ação. Portanto, se os registros forem idênticos, as chaves de cache de ação também serão.

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

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

  2. Faça o download do código-fonte do Bazel e vá para a pasta do Bazel usando o comando abaixo. Você precisa do código-fonte para analisar os registros de execução com o analisador de execlog.

    git clone https://github.com/bazelbuild/bazel.git
    cd bazel
    
  3. Usar o analisador de registros de execução para converter os registros em texto. A invocação a seguir também classifica as ações no segundo registro para corresponder à ordem de ação no primeiro registro para facilitar a comparação.

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