Garantir a disponibilidade de recursos usando reservas de VM

Neste documento, explicamos como criar jobs para recursos reservados.

As reservas são um recurso do Compute Engine. Uma reserva oferece um nível de segurança muito alto na obtenção de capacidade para uma ou mais VMs com a configuração de hardware especificada. Uma reserva para uma VM gera custos para essa VM a partir da criação até a exclusão dela. No entanto, embora você esteja consumindo essa VM, o custo total será equivalente a uma VM sem reserva.

Em geral, as reservas são úteis quando a disponibilidade de capacidade é extremamente importante ou para evitar erros na aquisição de recursos. Especificamente no Batch, considere o uso de reservas dedicadas para ajudar a minimizar o tempo de agendamento do job ou tente usar reservas atuais enquanto elas não estiverem sendo usadas. Se você usou reservas insuficientes, como aquelas necessárias para descontos por compromisso de uso, poderá configurar jobs para tentar consumi-las enquanto não estiverem sendo usadas para otimizar os custos incorridos.

Para saber mais sobre reservas, consulte a documentação sobre reservas do Compute Engine.

Antes de começar

Restrições

Além das restrições gerais para reservas, o Batch também tem as seguintes restrições:

Requisitos

Nesta seção, resumimos os requisitos para que as VMs de um job consumam uma reserva. Para mais informações sobre todos os requisitos, consulte os requisitos gerais para reservas na documentação do Compute Engine e o procedimento para planejar sua configuração mais adiante neste documento.

  • Para que as VMs de um job geralmente sejam capazes de consumir uma reserva, todas as condições a seguir precisam ser atendidas:

    • O job e a reserva precisam especificar propriedades de VM que correspondam exatamente.

    • É preciso obedecer a todas as restrições neste documento e a todos os outros requisitos gerais para reservas.

  • Para que cada uma das VMs de um job consuma uma reserva com êxito, ela precisa ter capacidade não utilizada disponível durante o tempo de execução da VM.

    A capacidade não utilizada de uma reserva é a diferença entre a contagem de VMs e o número de VMs que a consomem. As VMs tentam consumir reservas sempre que você tem capacidade de reserva não utilizada. Portanto, uma VM pode começar a consumir uma reserva quando é criada ou posteriormente no ambiente de execução. Uma VM não para de consumir uma reserva até que a VM pare de ser executada ou ela seja excluída.

    Dependendo da capacidade de reserva total não utilizada, nenhuma, algumas ou todas as VMs de um job podem consumir reservas, e a quantidade de VMs reservadas pode variar durante o tempo de execução do job.

Criar e executar um job que possa consumir VMs reservadas

  1. Planeje a configuração. Para garantir que o job e a reserva sejam compatíveis, conclua as etapas a seguir.

    Para consumir uma reserva que já existe, crie um job com uma configuração correspondente. Caso contrário, se você planeja criar uma nova reserva, selecione as opções de configuração que preferir.

    1. Determine as propriedades de reserva. Devido às restrições, o tipo de compartilhamento precisa ser single-project, que é a opção padrão para uma reserva. Determine os valores que você quer usar para as seguintes propriedades de reserva:

      • Tipo de consumo*
      • Contagem de VMs

      *O tipo de consumo da reserva (direcionado especificamente ou consumido automaticamente) determina quais VMs podem consumi-la.

      A contagem de VM representa a capacidade total de uma reserva. Ao decidir esse valor, considere o número de VMs do job.

    2. Determine as propriedades da VM para o job e a reserva. Devido às restrições, nem o job nem a reserva podem especificar uma política de posicionamento compacto, que é a opção padrão para reservas e jobs. Determine os valores que você quer usar para as seguintes propriedades da VM, que precisam corresponder exatamente à reserva e ao job:

      • Projeto
      • Zona*
      • Tipo de máquina
      • Plataforma mínima de CPU (se houver)
      • Tipo e contagem de GPU (se houver)
      • Tipo e contagem de SSD local (se houver)
      • Afinidade de reserva#

      *As VMs do job precisam estar localizadas na mesma zona que as VMs reservadas. Inclua essa zona no campo allowedLocations[] do job ou, se omitir o campo allowedLocations[], defina o local do job como a região que contém essa zona.

      O job precisa definir todas essas propriedades usando os subcampos policy ou um modelo de instância de VM. Um job não pode especificar uma combinação de subcampos policy e um modelo.

      Não é possível definir um campo opcional para um recurso e omitir do outro. Defina ou omita o campo opcional para a reserva e o job. Se o job especificar um modelo de instância de VM, isso também se aplicará aos campos do modelo especificado.

      #O tipo de consumo da reserva determina a afinidade de reserva necessária para as VMs do job, que você precisa especificar no job da seguinte maneira:

      • Se o job estiver usando um modelo de instância de VM, o modelo precisará configurar a afinidade de reserva, conforme explicado na documentação de reservas.
      • Se o job não estiver usando um modelo e a reserva for especificamente visada, especifique o nome da reserva no campo reservation do job.
      • Caso contrário, se o job não estiver usando um modelo e a reserva for consumida automaticamente, omita o campo reservation do job.
  2. Prepare a reserva. Crie a reserva que você quer que as VMs do job consumam, caso ainda não tenha feito isso. Verifique se a reserva tem as propriedades que você planejou.

  3. Crie e execute o job. É possível criar e executar um job que consuma VMs da reserva preparada usando a CLI gcloud ou a API Batch:

    gcloud

    1. Crie um arquivo JSON que especifique os detalhes de configuração do job que definem os subcampos do recurso da instância de VM (instances[]) para corresponder exatamente às propriedades de VM de uma reserva.

      Por exemplo, para criar um job de script básico que consuma VMs de uma reserva, crie um arquivo JSON com o seguinte conteúdo:

      {
        "taskGroups": [
          {
            "taskSpec": {
              "runnables": [
                {
                  "script": {
                    "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
                  }
                }
              ]
            },
            "taskCount": 3
          }
        ],
        "allocationPolicy": {
          "instances": [
            {
              VM_RESOURCES
            }
          ],
        },
        "logsPolicy": {
          "destination": "CLOUD_LOGGING"
        }
      }
      

      Substitua VM_RESOURCES pelos recursos de VM que correspondem à reserva que você quer que o job consumir especificando os subcampos instances[] planejados nas etapas anteriores.

      Por exemplo, comece com o seguinte valor para VM_RESOURCES:

      "installGpuDrivers": INSTALL_GPU_DRIVERS,
      "policy": {
        "machineType": "MACHINE_TYPE",
        "minCpuPlatform": "MIN_CPU_PLATFORM",
        "accelerators": [
          {
            "type": "GPU_TYPE",
            "count": GPU_COUNT
          }
        ],
        "disks": [
          {
            "newDisk": {
              "sizeGb": LOCAL_SSD_SIZE,
              "type": "local-ssd"
            },
            "deviceName": "LOCAL_SSD_NAME"
          }
        ],
        "reservation": "SPECIFIC_RESERVATION_NAME"
      }
      

      Para usar esse valor, faça todas as mudanças a seguir:

      1. Você quer usar um modelo de instância?

        • Sim: substitua o campo policy pelo campo instanceTemplate e especifique um modelo de instância de VM atual que corresponda à reserva. Por exemplo, consulte o exemplo de código para usar um modelo de instância de VM. Se a reserva usar GPUs ou SSDs locais, também será necessário configurar os campos installGpuDrivers e volumes[] do job, respectivamente. Caso contrário, pule as outras mudanças.

        • Não: substitua MACHINE_TYPE pelo mesmo tipo de máquina da reserva.

      2. A reserva inclui uma plataforma mínima de CPU?

        • Sim:substitua MIN_CPU_PLATFORM pela mesma plataforma de CPU mínima.

        • Não:remova o campo minCpuPlatform.

      3. A reserva inclui GPUs?

        • Sim: substitua INSTALL_GPU_DRIVERS, GPU_TYPE e GPU_COUNT para corresponder à reserva. Por exemplo, consulte o exemplo de código para usar GPUs.

        • Não:remova os campos installGpuDrivers e accelerators[].

      4. A reserva inclui SSDs locais?

        • Sim: substitua LOCAL_SSD_SIZE e LOCAL_SSD_NAME para corresponder à reserva e ative os SSDs locais adicionando o campo volumes[] ao job. Por exemplo, consulte o exemplo de código para usar SSDs locais.

        • Não:remova o campo disks[].

      5. A reserva usa o tipo de consumo especificamente segmentado?

        • Sim: substitua SPECIFIC_RESERVATION_NAME pelo nome da reserva.

        • Não:remova o campo reservation.

      Por exemplo, suponha que você esteja usando uma reserva consumida automaticamente para VMs n2-standard-32 que não especifica nenhuma plataforma mínima de CPU, GPUs ou SSDs locais. Além disso, não especifique um modelo de instância de VM. Nesse caso, é necessário substituir VM_RESOURCES pelo seguinte valor:

      "policy": {
        "machineType": "n2-standard-32"
      }
      
    2. Para criar e executar o job, use o comando gcloud batch jobs submit:

      gcloud batch jobs submit JOB_NAME \
        --location LOCATION \
        --config JSON_CONFIGURATION_FILE
      

      Substitua:

      • JOB_NAME: o nome do job.

      • LOCATION: o local do job. A menos que o job especifique o campo allowedLocations[], ele precisará ser a região que contém a zona da reserva.

      • JSON_CONFIGURATION_FILE: o caminho de um arquivo JSON com os detalhes de configuração do job.

    API

    Faça uma solicitação POST para o método jobs.create que define os subcampos do recurso da instância de VM (instances[]) para corresponder exatamente às propriedades de VM de uma reserva.

    Por exemplo, para criar um job de script básico que consuma VMs de uma reserva, faça a seguinte solicitação:

    POST https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/jobs?job_id=JOB_NAME
    {
      "taskGroups": [
        {
          "taskSpec": {
            "runnables": [
              {
                "script": {
                  "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
                }
              }
            ]
          },
          "taskCount": 3
        }
      ],
      "allocationPolicy": {
        "instances": [
          {
            VM_RESOURCES
          }
        ],
      },
      "logsPolicy": {
        "destination": "CLOUD_LOGGING"
      }
    }
    

    Substitua:

    • PROJECT_ID: o ID do projeto (link em inglês).

    • LOCATION: o local do job. A menos que o job especifique o campo allowedLocations[], ele precisará ser a região que contém a zona da reserva.

    • JOB_NAME: o nome do job.

    • VM_RESOURCES: os recursos de VM que correspondem à reserva que você quer que o job consuma especificando os subcampos instances[] planejados nas etapas anteriores.

      Por exemplo, comece com o seguinte valor para VM_RESOURCES:

      "installGpuDrivers": INSTALL_GPU_DRIVERS,
      "policy": {
        "machineType": "MACHINE_TYPE",
        "minCpuPlatform": "MIN_CPU_PLATFORM",
        "accelerators": [
          {
            "type": "GPU_TYPE",
            "count": GPU_COUNT
          }
        ],
        "disks": [
          {
            "newDisk": {
              "sizeGb": LOCAL_SSD_SIZE,
              "type": "local-ssd"
            },
            "deviceName": "LOCAL_SSD_NAME"
          }
        ],
        "reservation": "SPECIFIC_RESERVATION_NAME"
      }
      

      Para usar esse valor, faça todas as mudanças a seguir:

      1. Você quer usar um modelo de instância?

        • Sim: substitua o campo policy pelo campo instanceTemplate e especifique um modelo de instância de VM atual que corresponda à reserva. Por exemplo, consulte o exemplo de código para usar um modelo de instância de VM. Se a reserva usar GPUs ou SSDs locais, também será necessário configurar os campos installGpuDrivers e volumes[] do job, respectivamente. Caso contrário, pule as outras mudanças.

        • Não: substitua MACHINE_TYPE pelo mesmo tipo de máquina da reserva.

      2. A reserva inclui uma plataforma mínima de CPU?

        • Sim:substitua MIN_CPU_PLATFORM pela mesma plataforma de CPU mínima.

        • Não:remova o campo minCpuPlatform.

      3. A reserva inclui GPUs?

        • Sim: substitua INSTALL_GPU_DRIVERS, GPU_TYPE e GPU_COUNT para corresponder à reserva. Por exemplo, consulte o exemplo de código para usar GPUs.

        • Não:remova os campos installGpuDrivers e accelerators[].

      4. A reserva inclui SSDs locais?

        • Sim: substitua LOCAL_SSD_SIZE e LOCAL_SSD_NAME para corresponder à reserva e ative os SSDs locais adicionando o campo volumes[] ao job. Por exemplo, consulte o exemplo de código para usar SSDs locais.

        • Não:remova o campo disks[].

      5. A reserva usa o tipo de consumo especificamente segmentado?

        • Sim: substitua SPECIFIC_RESERVATION_NAME pelo nome da reserva.

        • Não:remova o campo reservation.

      Por exemplo, suponha que você esteja usando uma reserva consumida automaticamente para VMs n2-standard-32 que não especifica nenhuma plataforma mínima de CPU, GPUs ou SSDs locais. Além disso, não especifique um modelo de instância de VM. Nesse caso, é necessário substituir VM_RESOURCES pelo seguinte valor:

      "policy": {
        "machineType": "n2-standard-32"
      }
      

A seguir