DEV Community

renanpyd
renanpyd

Posted on

Como aprendi Apache Spark: revisitando uma jornada pela Engenharia de Dados

Quando comecei a estudar Apache Spark, o ecossistema de Big Data era muito diferente do que conhecemos hoje.

Hadoop e MapReduce dominavam boa parte das conversas sobre processamento distribuído. Trabalhar com grandes volumes de dados normalmente significava pensar em clusters, HDFS, processamento em lote e muitas operações de leitura e escrita em disco.

> Foi nesse cenário que o Spark começou a chamar minha atenção.

**E esta série nasce justamente de uma ideia: revisitar meus antigos materiais de estudo sobre Apache Spark e reconstruí-los com o olhar que tenho hoje como profissional de Engenharia de Dados e IA.

Não quero simplesmente republicar anotações antigas.

Quero entender o que envelheceu, o que continua extremamente relevante e, principalmente, quais conceitos atravessaram diferentes gerações do Spark e continuam presentes na engenharia de dados moderna.**

## Por que revisitar Apache Spark?

Algumas tecnologias mudam tanto que estudar suas versões antigas parece arqueologia.

Spark é diferente.

As APIs evoluíram. O ecossistema mudou. RDDs deixaram de ser a principal abstração utilizada em muitas aplicações. DataFrames, Spark SQL, Catalyst, Structured Streaming e diversas otimizações passaram a ocupar um papel central.

Mas vários fundamentos continuam essenciais.

Conceitos como:

  • processamento distribuído;
  • particionamento;
  • transformações e ações;
  • lazy evaluation;
  • lineage;
  • DAGs;
  • shuffle;
  • execução distribuída;
  • tolerância a falhas;
  • serialização;
  • gerenciamento de memória;

continuam ajudando a explicar por que um job Spark funciona — ou por que ele fica terrivelmente lento.

E é justamente aí que estudar os fundamentos continua tendo valor.

Um aviso importante sobre esta série:
Esta não será simplesmente uma reprodução dos meus materiais antigos.

Alguns deles utilizam versões antigas do Spark e APIs que foram substituídas ou evoluíram significativamente.

Sempre que isso acontecer, vou separar três coisas:

  • Como funcionava
  • O comportamento ou API utilizada naquele momento da evolução do Spark.
  • O conceito por trás

A ideia de Engenharia de Dados que continua importante independentemente da versão.

Como pensamos nisso hoje: A maneira moderna de resolver ou compreender o mesmo problema. Isso significa que eventualmente veremos código antigo. E isso é proposital.

> Código legado também conta a história de uma tecnologia.

De Hadoop MapReduce ao Spark

Uma das ideias que tornou Spark especialmente interessante foi reduzir a dependência de sucessivas operações de leitura e escrita em disco durante determinados tipos de processamento.

Em workloads iterativos e análises interativas, isso fazia uma diferença enorme.

Mas seria simplista resumir Spark a:

"Spark é rápido porque processa tudo em memória."

A arquitetura é muito mais interessante.

Spark introduziu um modelo de computação distribuída baseado em abstrações capazes de manter informações sobre como os dados foram produzidos.

Uma dessas abstrações tornou-se fundamental para entender os primeiros anos do projeto:

RDD — Resilient Distributed Dataset

Um RDD representa uma coleção distribuída de dados que pode ser processada paralelamente.

Mas a parte realmente interessante não é apenas o fato de os dados estarem distribuídos.

É a combinação de:

  • particionamento;
  • imutabilidade;
  • operações funcionais;
  • execução lazy;
  • lineage;
  • recomputação;
  • tolerância a falhas.

Essas ideias ajudaram a criar um modelo poderoso para computação distribuída.

Em 2012, o trabalho sobre Resilient Distributed Datasets recebeu o prêmio de melhor artigo no NSDI.

Anos depois, muitas das abstrações de mais alto nível utilizadas no Spark seriam construídas sobre fundamentos estabelecidos nesse período.

E então vieram DataFrames, Spark SQL e muito mais

A história não parou nos RDDs.

O ecossistema evoluiu.

Spark SQL tornou o processamento de dados estruturados muito mais acessível.

DataFrames elevaram o nível de abstração.

O Catalyst Optimizer passou a desempenhar um papel fundamental na otimização de consultas.

O projeto Tungsten trouxe importantes avanços na execução e no gerenciamento de memória.

Structured Streaming aproximou processamento batch e streaming sob um modelo mais uniforme.

E Spark tornou-se uma das principais tecnologias da Engenharia de Dados moderna.

É essa evolução que quero explorar ao longo desta série.

O que vamos estudar

Nos próximos artigos vamos passar por assuntos como:

  • arquitetura do Apache Spark;
  • RDDs;
  • transformations e actions;
  • lazy evaluation;
  • SparkContext;
  • execução distribuída;
  • Client Mode e Cluster Mode;
  • particionamento;
  • joins e shuffles;
  • accumulators;
  • broadcast variables;
  • JSON;
  • DataFrames;
  • Spark SQL;
  • schemas;
  • fontes de dados;
  • window functions;
  • Spark Streaming;
  • testes;
  • gerenciamento de memória;
  • memoryOverhead;
  • otimização e troubleshooting.

Também vamos comparar algumas APIs históricas com a forma como resolveríamos os mesmos problemas atualmente.

O objetivo não é decorar Spark

Depois de trabalhar com Engenharia de Dados por algum tempo, uma coisa fica cada vez mais clara:

saber escrever código Spark não significa necessariamente saber Spark.

É relativamente fácil escrever:

df.groupBy("customer_id").count()
Enter fullscreen mode Exit fullscreen mode

O mais importante é conseguir perguntar:

  • Quantas partições existem?
  • Haverá shuffle?
  • Qual será o volume movimentado pela rede?
  • Existe data skew?
  • Como o plano será executado?
  • O dataset cabe adequadamente nas partições?

O problema está no driver ou nos executors?

O gargalo é CPU, memória, disco ou rede?

Essa transformação realmente precisa existir?

É esse tipo de raciocínio que transforma conhecimento de uma API em conhecimento de Engenharia de Dados distribuída.

Próximo artigo

Na Parte 1, vamos começar pelos fundamentos:

O que é Apache Spark e por que sua arquitetura foi tão importante?

Vamos entender:

o problema que Spark buscava resolver;

a relação histórica com Hadoop;

o papel dos RDDs;

processamento em memória;

tolerância a falhas;

e como essas decisões influenciaram o Spark que usamos atualmente.

Esta série será uma viagem pelas versões do Spark, mas principalmente pelos conceitos de Engenharia de Dados que sobreviveram a elas.

Nos vemos na Parte 1.

Top comments (0)