Google PDE: Spark, Dataproc e Processamento de Dados Distribuído — Guia de estudos
Faz parte do Google Professional Data Engineer — Guia de estudos. Pratique com respostas verificadas no centro de exames da Google, ou faça testes cronometrados no ExamRoll.io.
Visão Geral
O Apache Spark no Google Cloud Dataproc oferece uma plataforma gerenciada e elástica para processamento de dados distribuído. Você pode escolher entre clusters Dataproc de longa duração ou efêmeros e o Dataproc Serverless para Spark, dependendo das necessidades de controle, variabilidade do tempo de execução e sobrecarga de gerenciamento. O Spark oferece abstrações resilientes (RDDs), APIs relacionais (DataFrames e Spark SQL) e um mecanismo de execução de DAG tolerante a falhas, otimizado para ETL iterativo e em lote em grande escala. No Google Cloud, o Cloud Storage substitui o HDFS para armazenamento durável e de baixo custo; o conector do BigQuery permite o descarregamento analítico direto; e o Dataproc Metastore centraliza o gerenciamento de esquemas. Soluções eficazes alinham os ciclos de vida de armazenamento e computação, ajustam o Spark à carga de trabalho, instrumentam a observabilidade e aplicam segurança com o princípio do menor privilégio e isolamento de rede.
Arquitetura do Dataproc: Clusters, Serverless, Armazenamento e Metastore
- Tipos de cluster e papéis dos nós
- Nós primários (master) hospedam o YARN, o HDFS NameNode (se usado) e as UIs do driver do Spark; o modo de alta disponibilidade (HA) usa múltiplos primários.
- Nós de trabalho (worker) executam os executores e os HDFS DataNodes (se usados).
- Workers secundários/auxiliares são tipicamente preemptivos/spot para capacidade elástica de menor custo, sem as funções do HDFS.
- As imagens agrupam versões de SO e componentes (por exemplo, 2.1-debian11, 2.2-ubuntu20); fixe as versões das imagens para controlar a compatibilidade do Spark/Hadoop e fazer upgrades de forma deliberada.
- O Component Gateway publica as UIs (Spark History Server, YARN RM) de forma segura via HTTPS.
- Dataproc Serverless para Spark
- Sem provisionamento de cluster, com autoscaling automático e cobrança por segundo para executores e drivers. Ideal para jobs esporádicos ou com picos de uso, ou para minimizar a sobrecarga operacional.
- Desvantagens: menos controles de baixo nível do que os clusters; a latência de início do job pode ser maior do que em clusters aquecidos (warm); use métricas e logs de eventos serverless para solucionar problemas.
- Autoscaling
- Políticas de autoscaling de cluster adicionam/removem workers com base em métricas do YARN/Spark e períodos de resfriamento (cooldowns), ajustando separadamente os grupos de workers primários e secundários.
- O autoscaling do Serverless é gerenciado pelo serviço; projete para ser paralelo por partição e evite gargalos serializados para obter o melhor escalonamento.
- Armazenamento e conectores
- Prefira o Google Cloud Storage (GCS) como o sistema de registro (system-of-record); ele desacopla a computação do armazenamento, reduz o custo de discos persistentes e sobrevive aos ciclos de vida do cluster.
- O conector do GCS (gs://) se integra com o Hadoop/Spark. A escrita em object stores usa protocolos de commit; defina o algoritmo v2 do FileOutputCommitter para reduzir a sobrecarga de renomeação e acelerar os commits de jobs no GCS:
--conf mapreduce.fileoutputcommitter.algorithm.version=2
```
- Use Parquet/ORC com poda de colunas (column pruning) e empurramento de predicados (predicate pushdown). Gerencie arquivos pequenos por meio de compactação para atingir um alvo de 128–512 MiB por arquivo para uma varredura (scan) eficiente.
- Hive metastore
- Centralize esquemas e metadados de tabelas no Dataproc Metastore (um Apache Hive Metastore gerenciado) ou em um metastore baseado no Cloud SQL para compartilhar catálogos entre clusters.
- Use tabelas externas apontando para o GCS para durabilidade; particione por data/hora para limitar o custo da varredura (scan).
- Jobs, inicialização e workflows
- Submeta jobs do tipo spark, pyspark, spark-sql ou hadoop. Ações de inicialização instalam bibliotecas ou agentes adicionais na criação do cluster (por exemplo, conectores, bibliotecas Python).
- Templates de workflow parametrizam pipelines de múltiplos passos; eles podem criar clusters efêmeros por workflow e, em seguida, destruí-los. Isso melhora o isolamento e reduz o custo ocioso.
- Clusters efêmeros são recomendados para ETL em lote; os dados e o metastore residem fora do cluster (GCS, Dataproc Metastore, BigQuery).
- Integração com o BigQuery
- O conector Spark para BigQuery lê/escreve diretamente no BigQuery; considere a BigQuery Storage Read API para alta taxa de transferência (throughput) e a Write API para inserções de streaming com menor latência e semântica *exactly-once*.
- Para a manutenção de tabelas, execute operações `MERGE` ou sobrescritas de partição (partition overwrites) no BigQuery para finalizar as cargas de forma atômica.
### Modelo Spark, Ajuste de Desempenho e Confiabilidade
- APIs e execução
- RDDs: de baixo nível, imutáveis, com tipagem segura (type-safe) em Scala/Java; você controla o particionamento e a persistência.
- DataFrames/Datasets: relacionais, otimizados pelo Catalyst; prefira estes para ETL devido à otimização de consultas e geração de código.
- As transformações são lazy (preguiçosas) (map, filter, join); as ações disparam a execução (count, collect, save). O Spark constrói um DAG de estágios (stages) divididos por shuffles; as tarefas (tasks) rodam por partição.
- Particionamento e shuffle
- Particionamento de entrada: partições suficientes para utilizar todos os cores; comece com 2 a 4 vezes o total de cores dos executores. Controle via spark.default.parallelism (para RDDs) e opções do leitor (para DataFrames).
- Partições de shuffle: o padrão de 200 geralmente subprovisiona ou superprovisiona. Ajuste:
--conf spark.sql.shuffle.partitions= {total_executor_cores * 2 to 3}
```
- Tenha como alvo ~100–256 MiB por partição após transformações amplas (wide transforms); partições muito pequenas causam sobrecarga no agendador (scheduler) e muito grandes arriscam OOM (Out of Memory) no executor.
- O shuffle é o custo dominante para joins, groupBy e orderBy. Garanta memória e disco adequados para o executor; considere SSDs locais para shuffles pesados em clusters.
- Skew (assimetria) e estratégia de join
- Detecte skew (tempos de execução de tarefas com cauda longa, tamanhos de partição grandes). Mitigações:
- Faça broadcast de tabelas pequenas para evitar shuffles:
- Detecte skew (tempos de execução de tarefas com cauda longa, tamanhos de partição grandes). Mitigações:
--conf spark.sql.autoBroadcastJoinThreshold=64m
```
- Adicione "sal" (salt) às chaves de partições quentes (hot partitions); aplique pré-agregação no lado do map (map-side); filtre cedo.
- Habilite a Execução Adaptativa de Consultas (AQE) para agrupar (coalesce) partições pós-shuffle e lidar com joins assimétricos (skewed joins):
--conf spark.sql.adaptive.enabled=true
```
- Cache, checkpointing e linhagem (lineage)
- Faça cache de DataFrames intermediários “quentes” (hot) com moderação quando forem reutilizados; prefira MEMORY_AND_DISK para evitar OOM.
- Faça checkpoint de linhagens longas no GCS ou HDFS para limitar o reprocessamento em caso de falhas.
- Executores e alocação dinâmica
- Dimensione corretamente os executores para equilibrar paralelismo e sobrecarga de GC (Garbage Collection):
- Cores por executor: 2–5 para tarefas com I/O/CPU balanceados; menos cores reduzem as pausas de GC.
- Sobrecarga de memória (memory overhead): defina spark.yarn.executor.memoryOverhead para shuffles amplos.
- Habilite a alocação dinâmica com o serviço de shuffle externo em clusters para escalar executores com a carga de trabalho:
- Dimensione corretamente os executores para equilibrar paralelismo e sobrecarga de GC (Garbage Collection):
--conf spark.dynamicAllocation.enabled=true
--conf spark.shuffle.service.enabled=true
--conf spark.dynamicAllocation.minExecutors=0
--conf spark.dynamicAllocation.maxExecutors=200
```
- Padrões de tolerância a falhas para ETL em lote (batch)
- Escritas idempotentes: escreva em um caminho temporário/de staging e, em seguida, promova atomicamente com um commit em nível de diretório; para o BigQuery, escreva em uma tabela de staging e use MERGE:
MERGE target t USING staging s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET ...
WHEN NOT MATCHED THEN INSERT (...)
```
- Processamento incremental: use filtragem baseada em marca d’água (watermark) em partições de ingestion_date; mantenha um manifesto de processados no GCS para evitar reprocessamento.
- Manuseio de “dead-letter”: em erros de parse/validação, desvie registros inválidos para um caminho/tabela de quarentena com diagnósticos. Para imposição estrita de schema e DLQs (Dead-Letter Queues) nativas, considere o Dataflow; com o Spark, implemente um try/catch por registro e um sink separado.
Segurança, Observabilidade e Custo
- Identidade e acesso
- Execute clusters e jobs com contas de serviço dedicadas e com o princípio de privilégio mínimo (least-privilege) do IAM. Conceda apenas os papéis necessários, por exemplo:
roles/dataproc.workerpara as contas de serviço das instânciasroles/storage.objectViewerouobjectAdminpara os caminhos de E/S do GCSroles/bigquery.dataEditornos datasets de destino
- Para o Dataproc Serverless, use contas de serviço por job para delimitar o escopo de acesso.
- Execute clusters e jobs com contas de serviço dedicadas e com o princípio de privilégio mínimo (least-privilege) do IAM. Conceda apenas os papéis necessários, por exemplo:
- Isolamento de rede e criptografia
- Use clusters com IP privado em uma sub-rede VPC, restrinja as UIs do master com firewall e habilite o Acesso Privado do Google para GCS/BigQuery sem saída pública.
- Coloque os clusters em projetos de VPC Compartilhada (Shared VPC) para controle centralizado. Opcionalmente, habilite o Kerberos no Dataproc para autenticação dentro do cluster.
- Criptografe em repouso com CMEK: configure CMEK em buckets do GCS, Persistent Disks, Dataproc Metastore e BigQuery; use TLS em trânsito por padrão.
- Logging, histórico e métricas
- Habilite os logs de eventos do Spark para o GCS e implante o History Server:
--conf spark.eventLog.enabled=true
--conf spark.eventLog.dir=gs://bucket/spark-events/
```
- O Dataproc transmite os logs do driver e do YARN para o Cloud Logging; exporte para coletores (sinks) para retenção/análise forense.
- Monitore com as métricas do Cloud Monitoring: contêineres pendentes do YARN, CPU, memória, saúde do HDFS (se usado), throughput do GCS. Crie alertas para novas tentativas de estágio (stage retries) prolongadas, perda de executores e picos de execução especulativa.
- Análise de falhas: causas comuns incluem tarefas lentas (stragglers) induzidas por assimetria de dados (skew), OOM (Out of Memory) do executor durante o shuffle, falhas de commit no object store e perda de nós preemptivos/spot. Aumente a contagem de novas tentativas (retries) criteriosamente; retries excessivos podem amplificar o custo e o atraso.
- Otimização de custos
- Use clusters efêmeros ou o Dataproc Serverless para evitar custos com ociosidade; mantenha os dados no GCS para minimizar o uso de disco persistente.
- Adicione workers secundários preemptivos/spot para absorver picos de demanda; projete para recomputação, pois as tarefas em nós perdidos são repetidas. Não coloque masters em nós preemptivos.
- Dimensione corretamente os tipos de máquina e use o autoscaling para reduzir a capacidade quando as filas estiverem vazias. Prefira Parquet/ORC com poda de partição (partition pruning) para cortar custos de varredura e CPU.
- Evite arquivos pequenos compactando as saídas; menos arquivos e maiores reduzem a sobrecarga de metadados e o tempo de execução do job.
- Para jobs curtos e periódicos (por exemplo, um ETL Spark semanal de 30 minutos), workers preemptivos ou o modo serverless geralmente oferecem o melhor perfil de custo.
#### Cenário de Problema Prático
A Acme Retail está migrando um cluster Hadoop on-prem de 30 nós que executa ETLs noturnos com Spark e Hive para alimentar análises downstream. Eles querem reutilizar os jobs existentes com alterações mínimas, evitar o gerenciamento de clusters em tempo integral, persistir dados além do ciclo de vida do cluster e reduzir o custo de armazenamento.
Abordagem:
1) Armazenar dados e metadados em serviços gerenciados
- Armazene todos os dados brutos e curados no Cloud Storage usando Parquet com particionamento (por exemplo, dt=YYYY-MM-DD).
- Justificativa: O GCS é durável, de baixo custo e desacopla a computação do armazenamento, permitindo que clusters efêmeros e jobs serverless sejam executados sem discos persistentes. O Parquet particionado habilita o predicate pushdown e varreduras eficientes.
2) Centralizar o catálogo com o Dataproc Metastore
- Migre o metastore do Hive para o Dataproc Metastore. Crie tabelas externas do Hive que referenciam caminhos do GCS e mantenha a lógica de esquema/partição existente.
- Justificativa: Um metastore gerenciado permite que múltiplos clusters efêmeros e jobs serverless compartilhem definições de tabela sem a necessidade de executar uma instância de MySQL/PostgreSQL em alta disponibilidade (HA).
3) Usar clusters Dataproc efêmeros para ETL em lote e modelos de fluxo de trabalho (workflow templates) para orquestração
- Defina um workflow template que cria um cluster com a imagem necessária (por exemplo, 2.1-debian11), executa os jobs Spark (spark-sql e pyspark) e exclui o cluster após a conclusão. Adicione ações de inicialização para instalar quaisquer bibliotecas personalizadas.
- Justificativa: Clusters efêmeros eliminam o custo de ociosidade e isolam as dependências dos jobs. Os workflow templates fornecem repetibilidade e parametrização (datas, caminhos de entrada).
4) Habilitar o autoscaling e workers preemptivos
- Anexe uma política de autoscaling com um pequeno grupo de workers principais (core) e um pool maior de workers secundários preemptivos; ajuste os períodos de resfriamento (cooldowns) para reduzir a escala prontamente após a execução.
- Justificativa: Os workers principais mantêm a estabilidade do cluster; os workers preemptivos absorvem shuffles e transformações amplas (wide transformations) a um custo menor. As novas tentativas do Spark/YARN lidam com tarefas perdidas na preempção.
5) Integrar com o BigQuery através do conector Spark para BigQuery
- Para cargas de dimensões/fatos, escreva os resultados do Spark em tabelas de staging do BigQuery e, em seguida, execute instruções MERGE para atualizar os alvos atomicamente. Onde a substituição direta for segura, escreva em tabelas particionadas usando o modo de substituição de partição (partition overwrite).
- Justificativa: O BigQuery atende a análises e BI em escala; staging+MERGE produz upserts semelhantes a transações a partir do Spark em lote, reduzindo a inconsistência downstream.
6) Ajustar o Spark para desempenho e confiabilidade
- Defina as partições de shuffle em relação aos cores dos executores e habilite o AQE:
--conf spark.sql.shuffle.partitions=600
--conf spark.sql.adaptive.enabled=true
```
- Use broadcast joins para dimensões pequenas e faça checkpoint de linhagens (lineages) longas no GCS para estabilidade.
- Justificativa: O particionamento adequado reduz a assimetria (skew) e a sobrecarga do agendador; o AQE se adapta aos perfis de dados em tempo de execução; o checkpointing limita a recomputação após falhas.
Reforçar a segurança e a rede
- Execute clusters com contas de serviço dedicadas, concedendo apenas os papéis necessários para os caminhos do GCS, o metastore e os datasets do BigQuery. Crie clusters com IP privado em uma sub-rede restrita com Acesso Privado do Google e limite o acesso à UI por meio de regras de firewall.
- Justificativa: O privilégio mínimo e o isolamento de rede reduzem a superfície de ataque; a saída privada do plano de controle evita a exposição pública.
Instrumentar logging, histórico e alertas
- Habilite os logs de eventos do Spark para o GCS e implante o History Server; roteie os logs do driver/YARN para o Cloud Logging com retenção. Adicione alertas do Monitoring para contêineres pendentes por muito tempo, falhas repetidas de tarefas ou duração excessiva do job.
- Justificativa: Logs centralizados apoiam a análise de causa raiz; alertas proativos detectam assimetria (skew), OOMs ou E/S degradada precocemente.
Modernizar seletivamente com o Dataproc Serverless para cargas de trabalho ad hoc e picos elásticos
- Mova cargas de trabalho esporádicas ou exploratórias de Spark SQL para o Dataproc Serverless; mantenha os pipelines noturnos em clusters efêmeros até que sejam totalmente validados no serverless.
- Justificativa: O Serverless remove as operações de cluster e escala automaticamente, ideal para cargas imprevisíveis; os fluxos de trabalho existentes continuam com alterações mínimas de código.
Validar os committers do object store e o gerenciamento de arquivos pequenos
- Defina o algoritmo
FileOutputCommitterpara a versão v2 e compacte as saídas para 256–512 MiB por arquivo viarepartition/coalesceantes das escritas. - Justificativa: Object stores não possuem a operação de renomeação atômica; committers otimizados reduzem a sobrecarga de cópia/renomeação. A compactação mitiga o problema dos arquivos pequenos (small-files problem) para melhor desempenho e custo.
- Defina o algoritmo
Este design reutiliza os jobs Spark e Hive existentes com refatoração mínima, garante a durabilidade dos dados no GCS, centraliza esquemas, contém o raio de impacto de segurança, fornece observabilidade robusta e otimiza o custo por meio de clusters efêmeros, autoscaling, capacidade preemptiva e uso direcionado da execução serverless.
← Mensageria · Todos os domínios · Ingestão →
Pratique estas questões → · Prática cronometrada no ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Passe no seu exame →