Orientações de otimização do desempenho para o Spark no HDInsight e Azure Data Lake Storage Gen1

Ao otimizar o desempenho no Spark, tem de considerar o número de aplicações que serão executadas no cluster. Por predefinição, pode executar quatro aplicações em simultâneo no cluster HDI (Nota: a predefinição está sujeita a alterações). Pode optar por utilizar menos aplicações para poder substituir as predefinições e utilizar mais do cluster para essas aplicações.

Pré-requisitos

Parâmetros

Ao executar tarefas do Spark, eis as definições mais importantes que podem ser otimizadas para aumentar o desempenho no Data Lake Storage Gen1:

  • Num-executors – o número de tarefas simultâneas que podem ser executadas.

  • Executor-memória – a quantidade de memória alocada a cada executor.

  • Executor-núcleos – o número de núcleos alocados a cada executor.

Num-executors Os executores numéricos definirão o número máximo de tarefas que podem ser executadas em paralelo. O número real de tarefas que podem ser executadas em paralelo está vinculado à memória e aos recursos da CPU disponíveis no cluster.

Executor-memória Esta é a quantidade de memória que está a ser alocada a cada executor. A memória necessária para cada executor depende da tarefa. Para operações complexas, a memória tem de ser maior. Para operações simples como leitura e escrita, os requisitos de memória serão mais baixos. A quantidade de memória para cada executor pode ser visualizada no Ambari. No Ambari, navegue para Spark e veja o separador Configurações .

Executor-núcleos Isto define a quantidade de núcleos utilizados por executor, que determina o número de threads paralelos que podem ser executados por executor. Por exemplo, se executor-núcleos = 2, cada executor pode executar 2 tarefas paralelas no executor. Os núcleos de executor necessários dependerão da tarefa. Os trabalhos pesados de E/S não requerem uma grande quantidade de memória por tarefa para que cada executor possa lidar com tarefas mais paralelas.

Por predefinição, são definidos dois núcleos YARN virtuais para cada núcleo físico ao executar o Spark no HDInsight. Este número fornece um bom equilíbrio entre simultaneidade e quantidade de contexto que muda de vários threads.

Orientação

Ao executar cargas de trabalho analíticas do Spark para trabalhar com dados no Data Lake Storage Gen1, recomendamos que utilize a versão mais recente do HDInsight para obter o melhor desempenho com Data Lake Storage Gen1. Quando a sua tarefa estiver mais intensiva em E/S, determinados parâmetros podem ser configurados para melhorar o desempenho. Data Lake Storage Gen1 é uma plataforma de armazenamento altamente dimensionável que consegue lidar com débito elevado. Se a tarefa consistir principalmente em leituras ou escritas, aumentar a simultaneidade de E/S de e para Data Lake Storage Gen1 pode aumentar o desempenho.

Existem algumas formas gerais de aumentar a simultaneidade dos trabalhos intensivos de E/S.

Passo 1: determinar quantas aplicações estão em execução no cluster – deve saber quantas aplicações estão em execução no cluster, incluindo a atual. Os valores predefinidos para cada definição do Spark pressupõem que existem 4 aplicações em execução em simultâneo. Por conseguinte, só terá 25% do cluster disponível para cada aplicação. Para obter um melhor desempenho, pode substituir as predefinições ao alterar o número de executores.

Passo 2: definir executor-memória – a primeira coisa a definir é o executor-memória. A memória estará dependente da tarefa que vai executar. Pode aumentar a simultaneidade ao alocar menos memória por executor. Se vir exceções de memória esgotada quando executar a tarefa, deve aumentar o valor para este parâmetro. Uma alternativa é obter mais memória através de um cluster que tenha maiores quantidades de memória ou aumente o tamanho do cluster. Mais memória permitirá a utilização de mais executores, o que significa mais simultaneidade.

Passo 3: definir executor-núcleos – para cargas de trabalho intensivas de E/S que não têm operações complexas, é bom começar com um elevado número de executor-núcleos para aumentar o número de tarefas paralelas por executor. A definição de executor-núcleos para 4 é um bom começo.

executor-cores = 4

Aumentar o número de núcleos de executor irá dar-lhe mais paralelismo para que possa experimentar diferentes núcleos de executor. Para trabalhos com operações mais complexas, deve reduzir o número de núcleos por executor. Se os núcleos de executor forem definidos acima de 4, a recolha de lixo poderá tornar-se ineficiente e degradar o desempenho.

Passo 4: determinar a quantidade de memória YARN no cluster – estas informações estão disponíveis no Ambari. Navegue para YARN e veja o separador Contigs. A memória YARN é apresentada nesta janela. Tenha em atenção que, enquanto estiver na janela, também pode ver o tamanho predefinido do contentor YARN. O tamanho do contentor YARN é o mesmo que a memória por parâmetro do executor.

Memória total do YARN = nós * memória YARN por nó

Passo 5: Calcular executores numéricos

Calcular a restrição de memória – o parâmetro num-executors está limitado pela memória ou pela CPU. A restrição de memória é determinada pela quantidade de memória YARN disponível para a sua aplicação. Pegue na memória total do YARN e divida-a por executor-memória. A restrição tem de ser desdimensionada para o número de aplicações, pelo que dividimos pelo número de aplicações.

Restrição de memória = (memória total do YARN/memória do executor) / # de aplicações

Calcular a restrição da CPU – a restrição da CPU é calculada como o total de núcleos virtuais divididos pelo número de núcleos por executor. Existem dois núcleos virtuais para cada núcleo físico. Semelhante à restrição de memória, dividimos pelo número de aplicações.

núcleos virtuais = (nós no cluster * # de núcleos físicos no nó * 2) restrição da CPU = (total de núcleos virtuais/# de núcleos por executor) / # de aplicações

Definir executores numéricos – o parâmetro num-executors é determinado ao assumir o mínimo da restrição de memória e da restrição da CPU.

num-executors = Min (total de Núcleos virtuais/# de núcleos por executor, memória YARN disponível/executor-memória) Definir um número mais elevado de executores numéricos não aumenta necessariamente o desempenho. Deve considerar que adicionar mais executores irá adicionar uma sobrecarga adicional para cada executor adicional, o que pode potencialmente degradar o desempenho. Os executores numéricos estão vinculados pelos recursos do cluster.

Cálculo de Exemplo

Digamos que tem atualmente um cluster composto por 8 nós D4v2 que está a executar duas aplicações, incluindo a que vai executar.

Passo 1: determinar quantas aplicações estão a ser executadas no cluster – sabe que tem duas aplicações no cluster, incluindo a que vai executar.

Passo 2: definir executor-memória – para este exemplo, determinamos que 6 GB de executor-memória serão suficientes para trabalhos intensivos de E/S.

executor-memory = 6GB

Passo 3: definir os núcleos de execução – uma vez que se trata de uma tarefa intensiva de E/S, podemos definir o número de núcleos para cada executor para quatro. Definir núcleos por executor para maiores do que quatro pode causar problemas de recolha de lixo.

executor-cores = 4

Passo 4: determinar a quantidade de memória YARN no cluster – navegamos para o Ambari para descobrir que cada D4v2 tem 25 GB de memória YARN. Uma vez que existem 8 nós, a memória yarn disponível é multiplicada por 8.

Memória total do YARN = nós * memória YARN* por nó Memória total do YARN = 8 nós * 25 GB = 200 GB

Passo 5: Calcular executores numéricos – o parâmetro num-executors é determinado ao assumir o mínimo da restrição de memória e a restrição da CPU dividida pelo # das aplicações em execução no Spark.

Calcular a restrição de memória – a restrição de memória é calculada como a memória yarn total dividida pela memória por executor.

Restrição de memória = (memória total do YARN/memória do executor) / # de aplicações Restrição de memória = (200 GB / 6 GB) / 2 Restrição de memória = 16 (arredondado) Calcular restrição da CPU - A restrição da CPU é calculada como o total de núcleos de yarn divididos pelo número de núcleos por executor.

Núcleos YARN = nós no cluster * # de núcleos por nó * 2 núcleos YARN = 8 nós * 8 núcleos por D14 * 2 = 128 restrição de CPU = (total de núcleos YARN/# de núcleos por executor) / # de restrição de CPU de aplicações = (128 /4) / Restrição de CPU 2 = 16

Definir executores numéricos

num-executors = Min (restrição de memória, restrição de CPU) num-executor = Min (16, 16) num-executors = 16