Análise do Spark kernel (6) análise do princípio operacional Spark Shuffle

1. Os pontos principais do Shuffle

1.1 ShuffleMapStage 与 FinalStage

Insira a descrição da imagem aqui
Ao dividir os estágios, o último estágio é denominado FinalStage, que é essencialmente um objeto ResultStage, e todos os estágios anteriores são denominados ShuffleMapStage.

ShuffleMapStage 的结束伴随着 shuffle 文件的写磁盘。

ResultStage basicamente corresponde ao operador de ação no código, a saber将一个函数应用在 RDD 的各个 partition 的数据集上,意味着一个 job 的运行结束。

1.2 Número de tarefas no Shuffle

1. Determinar o número de tarefas no lado do mapa

O número de tarefas no processo de reprodução aleatória é determinado pelo número de partições RDD, e o número de partições RDD está intimamente relacionado ao parâmetro spark.default.parallelism.

No modo Yarn Cluster, se spark.default.parallelism não for definido manualmente, há:

Others: total number of cores on all executor nodes or 2, whichever is larger.
spark.default.parallelism = max(所有 executor 使用的 core 总数, 2)

Se a configuração manual for realizada, então:

spark.default.parallelism = 配置值

Existe outra configuração importante:

The maximum number of bytes to pack into a single partition when reading files.
spark.files.maxPartitionBytes = 128 M (默认)

Representa o número máximo de bytes de dados que podem ser armazenados em uma partição do rdd. Se um arquivo de 400 MB for dividido em apenas duas áreas, ocorrerá um erro durante a ação.

Quando um aplicativo Spark é executado, um sparkContext é gerado e dois parâmetros são gerados ao mesmo tempo. Os valores desses dois parâmetros são derivados do spark.default.parallelism obtido acima:

sc.defaultParallelism = spark.default.parallelism
sc.defaultMinPartitions = min(spark.default.parallelism,2)

Quando os parâmetros acima são determinados, o número de partições RDD pode ser calculado:
(1) RDD gerado paralelizando o método de coleta de scala

val rdd = sc.parallelize(1 to 10)

Dessa forma, se o número de partições não for especificado durante a operação de paralelização, haverá:rdd 的分区数 = sc.defaultParallelism

(2) RDD gerado por textFile no sistema de arquivos local

val rdd = sc.textFile(“path/file”)

O número de partições de rdd = max (o número de fragmentos do arquivo local, sc.defaultMinPartitions)

(3) RDD gerado no sistema de arquivos HDFS

rdd 的分区数 = max(HDFS 文件的 Block 数目, sc.defaultMinPartitions)

(4) Obter dados da tabela de dados HBase e converter para RDD

rdd 的分区数 = Table 的 region 个数

(5) DataFrame convertido em arquivos json (ou parquet, etc.) obtendo

rdd 的分区数 = 该文件在文件系统中存放的 Block 数目

(6) O Spark Streaming obtém o número de partições correspondentes às mensagens Kafka

Com base no receptor:

Na abordagem do Receptor, a partição no Spark e a partição no kafka não estão relacionadas, portanto, se aumentarmos o número de partições para cada tópico, aumentaremos apenas os threads para processar os tópicos consumidos por um único Receptor. Mas isso não aumentou o paralelismo do Spark no processamento de dados.

Baseado em DirectDStream:

O Spark criará tantas partições RDD quanto as partições Kafka e lerá dados do Kafka em paralelo, portanto,
há um mapeamento um-para-um entre as partições Kafka e as partições RDD.

2. Determinar o número de tarefas no lado da redução

Reduz a agregação de dados 一部分聚合算子可以手动指定 reducetask 的并行度, se não for especificado, serámap 端的最后一个 RDD 的分区数作为其分区数,那么分区数就决定了 reduce 端的 task 的个数。

1.3 Leitura de dados no lado reduzido

De acordo com a divisão dos estágios, sabemos que a tarefa do lado do mapa e a tarefa do lado da redução não estão no mesmo estágio, a tarefa do mapa está localizada em ShuffleMapStage, a tarefa de redução está localizada no ResultStage e a tarefa do mapa será executada primeiro. Então, como a tarefa de redução executada mais tarde sabe de onde extrair o mapa? E quanto aos dados após a tarefa ser colocada?

O processo de extração de dados no lado da redução é o seguinte:

(1) Após a tarefa de mapa ser executada, o status do cálculo e a localização de pequenos arquivos no disco serão encapsulados no objeto mapStatue e, em seguida, o objeto MapOutPutTrackerWorker neste processo enviará o objeto mapStatus para o objeto MapOutPutTrackerMaster do processo de Driver;

(2)在 reduce task 开始执行之前会先让本进程中的 MapOutputTrackerWorker 向Driver 进程中的 MapoutPutTrakcerMaster 发动请求,请求磁盘小文件位置信息;

(3)当所有的 Map task 执行完毕后,Driver 进程中的 MapOutPutTrackerMaster就掌握了 所有的 磁盘小 文件的位 置信息 。此 时 MapOutPutTrackerMaster 会告诉MapOutPutTrackerWorker 磁盘小文件的位置信息;

(4) Após concluir as operações anteriores, BlockTransforService irá para o nó onde o Executor está localizado para extrair dados 默认会启动五个子线程. A quantidade de dados extraídos a cada vez não pode exceder 48M (a tarefa de redução extrai até 48M de dados a cada vez e armazena os dados extraídos em 20% da memória do Executor).

Dois, análise de HashShuffle

A discussão a seguir assume que cada Executor possui 1 núcleo de CPU.

2.1 HashShuffleManager não otimizado

O estágio de gravação aleatória serve principalmente para executar operadores do tipo embaralhamento (como reduceByKey) depois que o cálculo de um estágio é concluído e os dados processados ​​por cada tarefa são "divididos" por chave para o próximo estágio. 所谓“划分”,就是对相同的 key 执行 hash 算法,从而将相同 key 都写入同一个磁盘文件中,而每一个磁盘文件都只属于下游 stage 的一个 task。Antes de gravar os dados no disco, os dados serão gravados no buffer da memória e, quando o buffer da memória estiver cheio, ele irá transbordar para o arquivo do disco.

下一个 stage 的 task 有多少个,当前 stage 的每个 task 就要创建多少份磁盘文件。Por exemplo, o próximo estágio tem um total de 100 tarefas e cada tarefa do estágio atual deve criar 100 arquivos em disco. Se o estágio atual tiver 50 tarefas, haverá um total de 10 Executores e cada Executor executa 5 tarefas, então um total de 500 arquivos de disco serão criados em cada Executor e 5000 arquivos de disco serão criados em todos os Executores. Isso mostra que o número de arquivos de disco gerados por operações de gravação aleatória não otimizadas é extremamente impressionante.

O estágio de leitura aleatória é geralmente o que é feito no início de um estágio. 此时该 stage 的每一个 task 就需要将上一个 stage 的计算结果中的所有相同 key,从各个节点上通过网络都拉取到自己所在的节点上,然后进行 key 的聚合或连接等操作。Já que no processo de gravação aleatória, a tarefa de mapa cria um arquivo de disco para cada tarefa de redução no estágio de downstream. Portanto, no processo de leitura de embaralhamento, cada tarefa de redução só precisa ser puxada do nó onde todas as tarefas de mapa no estágio de upstream estão localizadas. Seu próprio arquivo de disco está bom.

shuffle read 的拉取过程是一边拉取一边进行聚合的。Cada tarefa de leitura aleatória terá seu próprio buffer e, a cada vez, só poderá extrair dados do mesmo tamanho do buffer do buffer e, em seguida, realizar agregação e outras operações por meio de um Mapa na memória. 聚合完一批数据后,再拉取下一批数据,并放到 buffer 缓冲中进行聚合操作。E assim por diante, até que finalmente todos os dados sejam extraídos e o resultado final seja obtido.

O princípio de funcionamento do HashShuffleManager não otimizado é mostrado na figura a seguir:
Insira a descrição da imagem aqui

2.2 HashShuffleManager otimizado

Para otimizar o HashShuffleManager, podemos definir um parâmetro :, spark.shuffle.consolidateFileso valor padrão deste parâmetro é falso, defina-o como verdadeiro para habilitar o mecanismo de otimização. De modo geral, se usarmos HashShuffleManager, é recomendável habilitar esta opção.

Após os mecanismos de consolidação abertos no processo de gravação aleatória, a tarefa não é criada para cada estágio de downstream de tarefa de um arquivo de disco, e desta vez haverá shuffleFileGroupo conceito, 每 个shuffleFileGroup 会对应一批磁盘文件,磁盘文件的数量与下游 stage 的 task 数量是相同的。um número de núcleo de CPU no Executor, em quantas tarefas podem ser executadas em paralelo . e第一批并行执行的每个 task 都会创建一个 shuffleFileGroup,并将数据写入对应的磁盘文件内。

Quando o executor do núcleo da CPU depois de executar uma tarefa de grupo, então a próxima tarefa de lote, o próximo lote irá reutilizar uma tarefa existente antes de shuffleFileGroup, que inclui arquivo de disco, ou seja, neste momento task会将数据写入已有的磁盘文件中,而不会写入新的磁盘文件中。e portanto,consolidate机制允许不同的 task 复用同一批磁盘文件,这样就可以有效将多个 task 的磁盘文件进行一定程度上的合并,从而大幅度减少磁盘文件的数量,进而提升 shuffle write的性能。

Supondo que o segundo estágio tenha 100 tarefas e o primeiro estágio 50 tarefas, ainda existem 10 executores (o número de CPUs do Executor é 1) e cada Executor executa 5 tarefas. Portanto, quando o HashShuffleManager não otimizado é usado, cada Executor gerará 500 arquivos em disco e todos os Executores gerarão 5000 arquivos em disco. Mas após a otimização neste momento, a fórmula de cálculo para o número de arquivos em disco criados por cada Executor é :, CPU core 的数量 * 下一个 stage 的 task 数量ou seja, cada Executor criará apenas 100 arquivos em disco neste momento, e todos os Executores criarão apenas 1000 arquivos em disco.

O princípio de funcionamento do HashShuffleManager otimizado é mostrado na figura abaixo:
Insira a descrição da imagem aqui

Três, análise SortShuffle

O mecanismo operacional do SortShuffleManager é dividido principalmente em dois tipos, um é 普通运行机制, o outro é bypass 运 行 机 制.当 shuffle read task 的数量小于等于 spark.shuffle.sort.bypassMergeThreshold 参数的值时(默认为 200),就会启用 bypass 机制。

3.1 Mecanismo operacional geral

Neste modo 数据会先写入一个内存数据结构中, neste momento, de acordo com diferentes operadores de embaralhamento, diferentes estruturas de dados podem ser selecionadas. Se for o operador shuffle da classe de agregação, como reduceByKey, a estrutura de dados Map será usada e o mapa será agregado enquanto grava na memória; se for o operador shuffle comum como join, a estrutura de dados Array será selecionada e escrita diretamente Na memória. Então, cada vez que um dado é gravado na estrutura de dados da memória, será avaliado se atingiu um certo limite crítico.如果达到临界阈值的话,那么就会尝试将内存数据结构中的数据溢写到磁盘,然后清空内存数据结构。

在溢写到磁盘文件之前,会先根据 key 对内存数据结构中已有的数据进行排序。Após a classificação, os dados serão gravados no arquivo do disco em lotes. O número do lote padrão é 10.000, ou seja, os dados classificados serão gravados no arquivo do disco em lotes na forma de 10.000 dados em cada lote. 写入磁盘文件是通过 Java 的 BufferedOutputStream 实现的。BufferedOutputStream é um fluxo de saída em buffer do Java. Primeiro, ele armazena os dados na memória e, em seguida, grava-os no arquivo de disco novamente quando o buffer de memória estourar. Isso pode reduzir o número de E / Ss do disco e melhorar o desempenho.

一个 task 将所有数据写入内存数据结构的过程中,会发生多次磁盘溢写操作,也就会产生多个临时文件。最后会将之前所有的临时磁盘文件都进行合并,这就是merge 过程,此时会将之前所有临时磁盘文件中的数据读取出来,然后依次写入最终的磁盘文件之中。 Além do que, além do mais,由于一个 task 就只对应一个磁盘文件,也就意味着该 task为下游 stage 的 task 准备的数据都在这一个文件中,因此还会单独写一份索引文件,其中标识了下游各个 task 的数据在文件中的 start offset 与 end offset。

SortShuffleManager possui um processo de mesclagem de arquivos em disco, o que reduz bastante o número de arquivos. Por exemplo, o primeiro estágio possui 50 tarefas, um total de 10 Executores, cada Executor executa 5 tarefas e o segundo estágio possui 100 tarefas. Uma vez que cada tarefa finalmente possui apenas um arquivo de disco, há apenas 5 arquivos de disco em cada Executor neste momento, e todos os Executores têm apenas 50 arquivos de disco.

O princípio de funcionamento do SortShuffleManager do mecanismo de operação normal é mostrado na figura abaixo:
Insira a descrição da imagem aqui

3.2 Mecanismo operacional de bypass

As condições de disparo do mecanismo de operação de desvio são as seguintes:

(1) O número de tarefas de shuffle map é menor que o valor do parâmetro spark.shuffle.sort.bypassMergeThreshold
(2) Não é um operador de shuffle agregado

Nesse ponto, é 每个 task 会为每个下游 task 都创建一个临时磁盘文件,并将数据按 key进行 hash 然后根据 key 的 hash 值,将 key 写入对应的磁盘文件之中。claro, ao gravar em um arquivo de disco, ele também é gravado primeiro no buffer de memória e, depois que o buffer estiver cheio, ele estourou e gravou no arquivo de disco. Finalmente, todos os arquivos de disco temporários também são mesclados em um arquivo de disco e um arquivo de índice separado é criado.

该过程的磁盘写机制其实跟未经优化的 HashShuffleManager 是一模一样的,因为都要创建数量惊人的磁盘文件,只是在最后会做一个磁盘文件的合并而已。Portanto, o pequeno número de arquivos finais do disco também torna o mecanismo de leitura aleatória melhor do que o HashShuffleManager não otimizado.

A diferença entre este mecanismo e o mecanismo operacional normal SortShuffleManager é:

(1) Mecanismo de gravação de disco diferente
(2) Sem classificação

Em outras palavras, os maiores benefícios de habilitar esse mecanismo são :shuffle write过程中,不需要进行数据的排序操作,也就节省掉了这部分的性能开销。

O princípio de funcionamento do SortShuffleManager do mecanismo de operação normal é mostrado na figura abaixo:
Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/weixin_43520450/article/details/108626739
Recomendado
Clasificación