OTMIZANDO DESEMPENHO NO SPARK: Pensando sobre Shuffling, Narrow and wide transformation
- #Data
- #Databricks
- #Python
Existem várias maneiras de otimizar o desempenho do spark, inclusive automaticamente, mas existem alguns processos que pensamos pouco sobre ele(pelo menos eu pensava pouco) e eu me perguntei se durante entrevista técnica alguém já teve que responder sobre como evitar um shuffling de dados, por exemplo. E, sim. Encontrei pessoas que tiveram que responder sobre isso. Sobre isso e sobre outras questões relacionadas a etapa de transformação.
Então, como iniciante, tu está praticando teus scripts em Spark...já sabe realizar filtros, agrupamentos, contagens e joins. Já sente pronto pra uma entrevista técnica. E a primeira pergunta do entrevistador é: Como otimizar o desempenho em Spark? Afinal, nenhuma organização vai investir em operações custosas e que as fazem perder tempo. "Ah, mas essa não é uma pergunta pra iniciante", então feche essa aba e volte quando for sênior.
Com o Spark a gente faz extract, transform e load. Dessas três a etapa em que mais investimos o nosso tempo (e o tempo o dinheiro da empresa)é o Transform, por isso é tão importante estudar sobre ela. É nessa etapa que tu vai demonstrar que sabe como é um stage com uma sequência que pode ser executada com eficiência e velocidade de processamento. E tem noção da otimização de desempenho, seja com base no tamanho dos dados ou na capacidade do cluster, por exemplo, ou nos dois.
Por que a maneira como tu organiza as transformações no Spark é importante?
Essa 'maneira' tem um impacto significativo no desempenho da aplicação. Quando falamos em otimizar desempenho, estamos falando em melhorar a eficiência e reduzir o tempo necessário para processar dados. Como dito anteriormente, nenhuma empresa vai investir em operações que as fazem perder tempo e que sejam custosas. Além disso, acredito que é uma vantagem pro candidato demonstrar que conhece a ferramenta e ainda sabe COMUNICAR como ela funciona. Não sei no mundo da tecnologia, mas na área da educação esse negócio de 'não sei explicar como funciona, mas sei fazer' doesn't work.
Tu já sabe que o Spark foi criado para resolver o problema de processamento de grandes volumes de dados distribuídos, então é importante conhecer alguns conceitos que podem impactar diretamente o tempo para processar esses dados. Processar os dados (e resolver os problemas relacionados) é a parte importante aqui. Principalmente se o desempenho estiver associado ao custo operacional e uso de recursos em nuvem. "Ah! São só alguns centavos de dólar", mas sai do bolso de quem?
Então, vamos lá! Como otimizar o desempenho no Spark?
Existe um ditado no mundo 'dev' que diz 'criamos uma solução e criamos outros 10 problemas'. Imagine que tu tem um grupo muito grande dados. Para evitar a leitura de TODOS os dados para trabalhar com, por exemplo, apenas 2 colunas, esses dados podem ser particionados. Podemos particionar dados em DataFrame, podemos particionar Tarefas (cluster). Essa decisão leva em conta o 'Business Requirements'. Agora durante a 'leitura' dos dados, as partições irrelevantes serão ignoradas e a quantidade de dados lidos e processados também diminuiu. Três 'palavras' pra ti: Par-a-béns. O particionamento melhora o desempenho e o gerenciamento dos dados.
Agora, imagine que tu particionou a tarefa em tarefas menores (pra não precisar ler e processar dados irrelevantes) e distribuiu entre os nós do cluster... 'alguém' vai ter que correr atrás de juntar tudo isso quando o bonitinho quiser fazer um groupBy. Assim, lição número 1, todas as operações em exigem que o spark mova dados entre as partições aciona o shuffling. Recapitulando: quando o spark precisa reagrupar dados espalhados em partições temos o efeito Shuffle.
Então, péra, tu particionou pra ler mais rápido, mas na hora de fazer 40 groupBy e 300 JOIN o negócio 'dá pau'(Shuffling)? Sim. O shuffling é uma parte necessária do processamento distribuído do spark, mas... pode impactar negativamente. Então, temos que ter um processar rápido e evitar o shuffling? Sim. E como fazemos isso? Evitando operações que fazem shuffling, ué. Fazendo repartition ou coalesce, ou broadcasting join...
Aí, o entrevistador vai perguntar como tu evita o shuffling no teu script spark só porque tu não estudou essa parte, alguns tem uma sorte desse tipo.
Tá, mas...Como otimizar o desempenho no Spark?Durante a etapa de transformação, tu já sabe que nós usamos operações de 'transformation' e operações de 'actions'. Onde as operações de transformações são operações que não são executadas imediatamente. Elas são apenas um plano de execução, um projeção lógica. Por exemplo, quando usamos select(), withColumn()...nenhum dados é processado até que uma ação seja executada. Enquanto que as operações de 'actions' são operações que executam transformações. Elas processam e retornam dados, como count() ou show().
Se os dados com os quais tu esta trabalhando podem ser processados localmente dentro de cada partição....então tu tem uma execução mais eficiente e direta.
Mas se é preciso coletar e reorganizar dados de várias partições de entrada... então tu tem uma execução mais demorada. E tu já sabe que quando o Spark precisa reagrupar dados espalhados em partições temos o efeito Shuffling.
Quando falamos em execução local, dentro de cada partição, estamos falando de Narrow Transformation.
Quando falamos em operações que podem acionar o efeito shuffling, estamos falando de Wide Transformation.
Agora que entedemos o comportamento das transformações em Spark, como otimizar o desempenho do spark?
Se tu sabe que as operações Wide transformations são mais custosas em termos de tempo de processamento devido ao shuffle de dados, pois envolve movimentar dados pela rede, então ela devem ser minimizadas ou maximizadas? Minimizadas. Devemos escolher minimizar as operações de wide transformations (que resultam em shuffles) e maximizar o número de narrow transformations que podem ser executadas dentro de um único stage.
Quais são as operações 'Narrow transformation', as 'Wide transformation', as operações de 'transformações' e 'ações' no Spark? São as operações que tu já usa no teu trabalho ou estudos, mas agora tu pode usar esse conceito pra explicar sobre otimização ou qual a relação delas com o desempenho no spark.
Ah, mas e quando eu uso `select` para incluir apenas as colunas necessárias, reduzindo o volume de dados processados e transferidos... estou otimizando? Sim.
E quando eu aplico filtros o mais cedo possível no pipeline de transformação para reduzir o volume de dados processados em etapas subsequentes... estou otimizando? Sim.
E quando eu uso um formato de arquivo que facilita a escrita e leitura dos dados... estou otimizando o processamento? Sim, está.
E quando eu preciso reutilizar dados e armazeno eles em memória utilizando `cache` ou `persist`...estou otimizando? Sim, está.
E o que é um stage? Um stage no Spark é um conjunto de operações que podem ser executadas sem redistribuição de dados. Enquanto tu estiver usando operações 'narrow transformation', tu tem um stage. Um novo stage é criado sempre que há uma wide transformation que exige um shuffle de dados entre partições.
Saiba mais sobre a etapa de transformação:
- Comprehensive Guide to Optimize Databricks, Spark and Delta Lake Workloads
- What is the difference between a Narrow Transformation and Wide Transformation
- What Is Data Transformation?
Bons estudos e bom fim de semana a todos.