Compartilhar via


Dimensionar clusters Ray no Azure Databricks

Saiba como ajustar o tamanho do cluster Ray para um desempenho ideal, incluindo dimensionamento automático, configuração de nó principal, clusters heterogêneos e alocação de recursos.

Criar um cluster do Ray no modo de dimensionamento automático

No Ray 2.8.0 e superior, os clusters do Ray iniciados no Azure Databricks dão suporte à integração com o dimensionamento automático do Azure Databricks. Essa integração do dimensionamento automático dispara o dimensionamento automático do cluster do Azure Databricks internamente, dentro do ambiente do Azure Databricks.

Para habilitar o dimensionamento automático, execute o seguinte comando:

Para a versão do Ray abaixo da 2.10:

from ray.util.spark import setup_ray_cluster

setup_ray_cluster(
  num_worker_nodes=8,
  autoscale=True,
)

Para o Ray versão 2.10 e em diante:

from ray.util.spark import setup_ray_cluster, shutdown_ray_cluster

setup_ray_cluster(
  min_worker_nodes=2,
  max_worker_nodes=4,
  num_cpus_per_node=4,
  collect_log_to_path="/dbfs/path/to/ray_collected_logs"
)

# Pass any custom Ray configuration with ray.init
ray.init(ignore_reinit_error=True)

A API ray.util.spark.setup_ray_cluster cria um cluster do Ray no Azure Spark. Internamente, ele cria um trabalho do Azure Spark em segundo plano. Cada tarefa do Azure Spark no trabalho cria um nó de trabalho do Ray e o nó principal do Ray é criado no driver. Os argumentos min_worker_nodes e max_worker_nodes representam o intervalo de nós de trabalho do Ray a serem criados e usados para cargas de trabalho do Ray. Se o argumento min_worker_nodes for mantido como indefinido, um cluster Ray de tamanho fixo será iniciado com max_worker_nodes número de trabalhos disponíveis. Para especificar o número de núcleos de CPU ou GPU atribuídos a cada nó de trabalho Ray, defina o argumento num_cpus_worker_node (valor padrão: 1) ou num_gpus_worker_node (valor padrão: 0).

Para a versão do Ray abaixo da 2.10, se o dimensionamento automático estiver habilitado, num_worker_nodes indicará o número máximo de nós de trabalho do Ray. O número mínimo padrão de nós de trabalho do Ray é zero. Essa configuração padrão significa que, quando o cluster Ray está ocioso, ele reduz verticalmente para zero nós de trabalho do Ray. Isso pode não ser ideal para resposta rápida em todos os cenários, mas pode reduzir significativamente os custos quando habilitado.

No modo de dimensionamento automático, num_worker_nodes não pode ser definido como ray.util.spark.MAX_NUM_WORKER_NODES.

Os seguintes argumentos configuram a velocidade de escalonamento e redução verticais:

  • autoscale_upscaling_speed representa o número de nós que podem estar pendentes como um múltiplo do número atual de nós. Quanto maior o valor, mais agressivo o escalonamento vertical. Por exemplo, se isso for definido como 1,0, o cluster poderá aumentar de tamanho em no máximo 100% em qualquer determinado momento.
  • autoscale_idle_timeout_minutes representa o número de minutos que precisam transcorrer antes que o dimensionador automático remova um nó de trabalho ocioso. Quanto maior o valor, mais agressiva a redução vertical.

Com o Ray 2.9.0 e superior, você também pode definir autoscale_min_worker_nodes para impedir que o cluster do Ray reduza verticalmente para zero trabalhos quando o cluster do Ray estiver ocioso, o que faria com que o cluster fosse encerrado.

Configurar recursos usados pelo nó de cabeçalho do Ray

Por padrão, para a configuração do Ray no Spark, o Azure Databricks restringe os recursos alocados no nó de cabeçalho do Ray para:

  • 0 núcleos de CPU
  • 0 GPUs
  • 128 MB de memória de heap
  • 128 MB de memória do repositório de objetos

Isso ocorre porque o nó de cabeçalho do Ray geralmente é usado apenas para coordenação global, não para executar tarefas do Ray. Os recursos do nó de driver do Azure Spark são compartilhados com vários usuários, portanto, a configuração padrão salva recursos no lado do driver do Azure Spark. Com o Ray 2.8.0 e superior, você pode configurar os recursos usados pelo nó de cabeçalho do Ray. Adicione os seguintes argumentos à API setup_ray_cluster:

  • num_cpus_head_node: definindo núcleos de CPU usados pelo nó de cabeçalho do Ray
  • num_gpus_head_node: definindo a GPU usada pelo nó de cabeçalho do Ray
  • object_store_memory_head_node: definindo o tamanho da memória do repositório de objetos pelo nó de cabeçalho do Ray

Suporte para clusters heterogêneos

Você pode criar um cluster do Ray no Spark para execuções de treinamento mais eficientes e econômicas e definir configurações diferentes entre o nó principal do Ray e os nós de trabalho do Ray. No entanto, todos os nós de trabalho do Ray precisam ter a mesma configuração. Os clusters do Azure Databricks não dão suporte total a clusters heterogêneos, mas você pode criar um cluster do Azure Databricks com diferentes tipos de instância de trabalho e de driver definindo uma política de cluster. Por exemplo:

{
  "node_type_id": {
    "type": "fixed",
    "value": "i3.xlarge"
  },
  "driver_node_type_id": {
    "type": "fixed",
    "value": "g4dn.xlarge"
  },
  "spark_version": {
    "type": "fixed",
    "value": "13.x-snapshot-gpu-ml-scala2.12"
  }
}

Ajustar a configuração do cluster Ray

A configuração recomendada para cada nó de trabalho do Ray é a seguinte: mínimo de 4 núcleos de CPU por nó de trabalho do Ray. Memória mínima de 10 GB de heap para cada nó de trabalho do Ray.

Portanto, ao chamar ray.util.spark.setup_ray_cluster, o Azure Databricks recomenda definir num_cpus_per_node como um valor maior que ou igual a 4.

Consulte a próxima seção para obter detalhes sobre como ajustar a memória do heap para cada nó de trabalho do Ray.

Alocação de memória para nós de trabalho do Ray

Cada nó de trabalho do Ray usa dois tipos de memória: memória de heap e memória do repositório de objetos.

O tamanho da memória alocada para cada tipo é determinado conforme descrito abaixo.

A memória total alocada para cada nó de trabalho do Ray é: RAY_WORKER_NODE_TOTAL_MEMORY = (SPARK_WORKER_NODE_PHYSICAL_MEMORY / MAX_NUMBER_OF_LOCAL_RAY_WORKER_NODES * 0.8)

MAX_NUMBER_OF_LOCAL_RAY_WORKER_NODES é o número máximo de nós de trabalho do Ray que podem ser iniciados no nó de trabalho do Azure Spark. Isso é determinado pelo argumento num_cpus_per_node ou num_gpus_per_node.

Se você não definir o argumento object_store_memory_per_node, o tamanho da memória do heap e o tamanho da memória do repositório de objetos alocados para cada nó de trabalho do Ray serão: RAY_WORKER_NODE_HEAP_MEMORY = RAY_WORKER_NODE_TOTAL_MEMORY * 0.7OBJECT_STORE_MEMORY_PER_NODE = RAY_WORKER_NODE_TOTAL_MEMORY * 0.3

Se você definir o argumento object_store_memory_per_node: RAY_WORKER_NODE_HEAP_MEMORY = RAY_WORKER_NODE_TOTAL_MEMORY - argument_object_store_memory_per_node

Além disso, o tamanho da memória do repositório de objetos por nó de trabalho do Ray é limitado pela memória compartilhada do sistema operacional. O valor máximo é: OBJECT_STORE_MEMORY_PER_NODE_CAP = (SPARK_WORKER_NODE_OS_SHARED_MEMORY / MAX_NUMBER_OF_LOCAL_RAY_WORKER_NODES * 0.8)

SPARK_WORKER_NODE_OS_SHARED_MEMORY é o tamanho do disco /dev/shm configurado para o nó de trabalho do Azure Spark.

Prática recomendada de dimensionamento

Confira o número de CPU e GPU para cada nó de trabalho Ray

Recomendamos definir o argumento num_cpus_worker_node como o número de núcleos de CPU por nó de trabalho do Apache Spark. Da mesma forma, definir num_gpus_worker_node como número de GPUs por nó de trabalho do Apache Spark é o ideal. Com essa configuração, cada nó de trabalho do Apache Spark inicia um nó de trabalho do Ray que utilizará totalmente os recursos de cada nó de trabalho do Apache Spark.

Defina a variável de ambiente RAY_memory_monitor_refresh_ms como 0 na configuração do cluster do Azure Databricks ao iniciar o cluster do Apache Spark.

Configuração de recursos de memória para cargas de trabalho híbridas Azure Spark e Ray

Se você executar cargas de trabalho híbridas do Spark e do Ray em um cluster do Azure Databricks, o Azure Databricks recomenda reduzir a memória do executor do Spark para um valor menor. Por exemplo, defina spark.executor.memory 4g na configuração do cluster do Azure Databricks.

O executor do Apache Spark é um processo Java que dispara o GC de forma preguiçosa e o cache do conjunto de dados do Apache Spark usa muita memória do executor do Apache Spark. Isso reduz a memória disponível que o Ray pode usar. Para evitar possíveis erros de memória insuficiente, reduza a configuração spark.executor.memory.

Configuração de recursos de computação para cargas de trabalho híbridas Azure Spark e Ray

Se você executar cargas de trabalho híbridas do Spark e do Ray em um cluster do Azure Databricks, recomendamos tornar os nós de cluster ou os nós de trabalho do Ray escalonáveis automaticamente. Por exemplo:

Se você tiver um número fixo de nós de trabalho disponíveis para iniciar um cluster do Azure Databricks, recomendamos habilitar o dimensionamento automático do Ray no Spark. Quando nenhuma carga de trabalho do Ray estiver em execução, o cluster Ray será reduzido verticalmente, permitindo que os recursos sejam liberados para uso por tarefas do Apache Spark. Quando as tarefas do Apache Spark forem concluídas e o Ray for usado novamente, o cluster Ray no Spark será escalado novamente para atender à demanda.

Além disso, você pode tornar os clusters Azure Databricks e Ray no Spark dimensionáveis automaticamente. Por exemplo, se você configurar os nós escalonáveis automáticos do cluster do Azure Databricks para um máximo de 10 nós, configure os nós de trabalho do Ray no Spark para um máximo de quatro nós e defina um nó de trabalho do Ray para operar por trabalho do Apache Spark, as cargas de trabalho do Ray poderão usar no máximo quatro recursos de nós em uma configuração de cluster. Em comparação, os trabalhos do Apache Spark podem alocar no máximo seis nós de recursos.