Introdução ao Spark — Parte 1

Tiago Diniz
How Kovi Work
Published in
4 min readDec 17, 2020
Photo by ev on Unsplash

Spark é super fácil de usar, tanto quanto SQL, mas não importa quantas horas eu gaste escrevendo código, simplesmente não sou capaz de armazenar todos os comandos na minha cabeça.

Se você deseja uma introdução rápida ao Spark SQL e está impaciente para escrever sua primeira consulta, ou se você é como eu e precisa de um artigo com dicas.

Apache Spark é um mecanismo para processamento de dados paralelo em grande escala. Uma das características surpreendentes é que ele expõe APIs em várias linguagens, como Scala, que é particularmente o meu preferido, mas existem muitos outros como SQL, Python, Java e R .

A primeira coisa a saber quando escrevemos um programa Spark é que, conforme executamos o código, não estamos necessariamente realizando nenhuma operação nos dados. Na verdade, a ferramenta possui dois tipos de chamadas: Transformações e Ações . O paradigma por trás das transformações do Spark é conhecido como “Lazy Evaluation”, o que significa que a compressão de dados real não começará até que chamemos uma ação.

Como o Apache Spark funciona de maneira distribuída, ele precisa de muitos recursos como memória e núcleos (CPU) para concluir um trabalho, na verdade, que depende dos dados de entrada e de alguns outros fatores. Portanto, “lazy” não é tão fácil. Às vezes, você não sabe se o seu trabalho de ativação está utilizando a quantidade correta de recursos ou não. Você tenta verificar isso através do Spark UI e se pergunta por que seu aplicativo está rodando por tanto tempo. Há certas maneiras que podem ajudar a melhorar o desempenho com os jobs do Spark. Neste artigo, vamos entender algumas maneiras que podem ajudar a melhorar o desempenho da sentença

Use o formato de arquivo correto

Escolher um formato de arquivo adequado é muito importante, um bom formato de arquivo pode proporcionar vários benefícios. No Hadoop, existem vários formatos de arquivo e eles têm seus próprios benefícios. Os formatos de arquivo mais usados ​​com Spark e Hadoop são Parquet, Avro e ORC.

Use a compactação de arquivo correta

A compactação de arquivos reduz o tamanho dos dados originais e os torna adequados para a operação de transferência / reprodução aleatória. O Apache Spark usa os codecs fornecidos pelo Hadoop para ler os arquivos compactados. Podemos obter a lista de tipos suportados na seguinte classe

org.apache.spark.sql.catalyst.util.CompressionCodecs.

Use a configuração correta — memória e executores

Este é, de longe, o fator mais importante no ajuste de “lazy”. O uso eficiente da memória é essencial para um bom desempenho. O Spark usa memória principalmente para armazenamento e execução. Durante a execução, também precisamos definir o número de executores para realizar uma tarefa específica. Às vezes, torna-se difícil obter a métrica adequada para a memória e os executores, pois cada trabalho é diferente e requer uma quantidade diferente de recursos para executar uma tarefa específica.

Ao atribuir memória e executores a um aplicativo spark, é necessário cuidar dos recursos para outras operações também como processos do sistema operacional, garbage collection, memória off-heap que ocupa algumas partes da memória e dos executores. Portanto, a partir dos recursos disponíveis, você precisa separar os recursos exigidos por esses processos.

Se você estiver usando um cluster compartilhado e habilitar a Alocação dinâmica de recursos, há mais uma propriedade que você precisa habilitar, que é chamada de Serviço de embaralhamento externo. Vamos entender o que essa propriedade faz. Suponha que um executor acabou de escrever os dados e se torna inativo e outro executor está lendo os dados gravados pelo primeiro executor, e digamos que a alocação dinâmica de recursos esteja habilitada, neste caso, o primeiro executor será morto enquanto está ocioso e assim os metadados relativos a esses dados serão perdidos e, sendo assim, o executor-2 não saberá mais ler os dados. Então, em vez de atribuir ao executor a responsabilidade pela ordem aleatória, o External Shuffle Service assume essa responsabilidade e executa o trabalho melhor sem perder nenhum dado.

spark.dynamicAllocation.enabled
spark.shuffle.service.enabled
spark.shuffle.service.port
spark.dynamicAllocation.schedulerBacklogTimeout
spark.dynamicAllocation.executorIdleTimeout

Serialização de dados

A serialização de dados ajuda a reduzir o uso de memória e também determina um bom desempenho da rede.

O Spark oferece suporte a duas bibliotecas de serialização, da seguinte maneira:

Java Serialization
Kryo Serialization

Java serialização é o padrão para a maioria dos tipos. Isso funciona com qualquer classe e é por isso que é mais flexível. No entanto, os objetos após a serialização são maiores em tamanho, por isso é lento em comparação com a serialização Kryo.

A serialização Kryo é o padrão para embaralhar RDDs e tipos simples. Este é 4x mais rápido e 10x mais compacto do que o Java Serializer. No entanto, este serializador requer que você registre classes personalizadas. Abaixo está a demonstração do código simples para registrar uma classe com a serialização Kryo.

Se seus objetos forem grandes, você também pode precisar aumentar o tamanho máximo do buffer. Aumente isto se obtiver uma exceção de “ limite de buffer excedido ” dentro do Kryo.

spark.kryoserializeer.buffer.max = 64Mb

No próximo post apresentarei mais alguns conceitos e dicas úteis.

--

--

How Kovi Work
How Kovi Work

Published in How Kovi Work

On this blog, Kovi's team share their daily challenges with our community, sharing process, insights and new technologies.

Tiago Diniz
Tiago Diniz