Notebook fora do cluster: migrar para Spark Connect no EMR on EKS
Ouvir artigo
gerado ao ouvirGerado apenas no primeiro play
Com tecnologia Amazon Polly + OmniVoice
Em 24/09/2026 o Amazon EMR on EKS ganhou sessões interativas via Spark Connect: o driver Spark vira um servidor gRPC no seu cluster EKS e o cliente PySpark fica no IDE de quem escreve o código. Tratei isso como uma migração, não como uma feature — e a parte difícil não é conectar, é o que o endpoint arrasta de rede, de IAM e de custo parado.
O anúncio de 24 de setembro de 2026 cabe em uma linha: o Amazon EMR on EKS passou a oferecer sessões Spark interativas via Spark Connect, do emr-7.14.0 em diante. A migração que ele habilita não cabe em uma linha. Tirar o kernel de dentro do cluster e deixar só o driver lá é uma troca de protocolo, de superfície de rede e de modelo de autorização ao mesmo tempo — e cada uma dessas três coisas tem um jeito próprio de falhar às duas da manhã.
O ponto de partida: o notebook que morava dentro do cluster
O padrão anterior de exploração interativa no EMR on EKS era um managed endpoint do tipo JUPYTER_ENTERPRISE_GATEWAY. O kernel roda no cluster, o Livy intermedeia, e o estado da sessão vive no mesmo pod que interpreta o código. Funciona, e cobra três preços que só aparecem na operação.
A ferramenta é imposta: quem escreve PySpark abandona o VS Code com linter, type checking e o mesmo pyproject.toml do repositório de produção, e passa a escrever numa aba de navegador. Depuração é print, não breakpoint.
O ciclo de deploy é falso: o código explorado no notebook não é o código que vai para produção. Ele é copiado, adaptado, e a adaptação é onde nasce o defeito que ninguém revisou.
A janela de manutenção contamina a análise: upgrade de add-on do EKS, rotação de node group, mudança de AMI — tudo isso derruba o kernel de quem estava no meio de uma investigação, porque o kernel é um pod do seu cluster.
Nenhum desses três problemas é sobre Spark. São problemas de acoplamento entre ambiente de desenvolvimento e plano de execução. É exatamente esse acoplamento que o Spark Connect corta: o cliente é uma biblioteca PySpark leve que fala gRPC com um servidor no driver. O que atravessa a rede é plano lógico, não bytecode.
A jornada, na ordem em que ela realmente acontece
- 1
1. Inventariar o que a sessão vai tocar
Antes de qualquer
create-security-configuration, liste os buckets S3, os bancos do Glue Data Catalog e as sub-redes que a exploração precisa. O execution role do endpoint é o teto de acesso de todo mundo que conectar nele — decidir isso depois é decidir errado. - 2
2. Provisionar o AWS Load Balancer Controller e uma sub-rede privada
O Spark Connect roteia gRPC por um Network Load Balancer interno, e o controller é quem o cria. Cluster sem controller instalado, ou sem sub-rede privada na VPC, não chega a criar o endpoint — falha de pré-requisito, não de configuração do Spark.
- 3
3. Criar a security configuration com namespace de sistema
A infraestrutura do Spark Connect roda num namespace de sistema, separado do namespace de usuário do virtual cluster. E a relação é 1:1 — uma security configuration por virtual cluster, sem reuso. Isso muda o desenho de multi-tenant antes de você escrever a primeira célula.
- 4
4. Recriar o virtual cluster com `--session-enabled true`
Sem essa flag e sem
--security-configuration-id, o virtual cluster não aceita endpoint Spark Connect. Para quem já rodaStartJobRunem produção, este é o passo com risco real: é um recurso novo ao lado do antigo, não uma alteração no lugar. - 5
5. Criar o primeiro endpoint e esperar o NLB
create-managed-endpoint --type SPARK_CONNECTcom--session-idle-timeout-in-minutes. O primeiro endpoint de cada cluster EKS demora minutos a mais: ele provisiona o NLB interno e o VPC interface endpoint (PrivateLink) que todos os endpoints seguintes reaproveitam. - 6
6. Fixar a versão do cliente no repositório, não no README
pyspark[connect]==3.5.8paraemr-7.14.0; a linhaemr-spark-8.1.0fixa o cliente empyspark[connect]==4.0.2. Divergência de versão dá erro de conexão ou comportamento estranho, e UDF Python com minor de Python diferente falha comPYTHON_VERSION_MISMATCH. - 7
7. Automatizar a renovação do token
GetManagedEndpointSessionCredentialsdevolve um token temporário usado comox-aws-proxy-authna URL do auth proxy. Quando ele expira, as chamadas gRPC falham com erro de autenticação e é preciso umaSparkSessionnova — helper no repositório, não instrução no wiki.
O que muda quando o protocolo vira gRPC
A arquitetura cliente-servidor do Spark Connect parece um detalhe de implementação e é a mudança mais operacional de todas. O cliente PySpark constrói um plano não resolvido, serializa e manda por gRPC sobre TLS; o driver no EKS resolve, otimiza e executa. Três consequências concretas:
A sessão sobrevive ao seu processo local. O contexto Spark é persistente e atravessa células e scripts — você mistura Python local com operação remota. Ctrl+C no cliente não derruba o driver, e é por isso que sessionIdleTimeoutInMinutes (padrão 60) é o único freio entre um desenvolvedor distraído e um pod de driver vivo a noite inteira.
A superfície de rede é nova e é interna. O gRPC entra por um NLB interno numa sub-rede privada, com um VPC interface endpoint na frente. Nada exposto na internet — mas há um componente de rede a mais no diagrama de ameaça, com Flow Logs, health check e grupo de segurança próprios.
O que não é DataFrame não passa. Spark Connect suporta DataFrame e SQL em PySpark; API baseada em RDD não é suportada. Isso não é asterisco de rodapé: é o critério de triagem de qual job legado pode ser explorado interativamente e qual precisa ser reescrito antes. Descobrir isso no meio da migração custa duas sprints.
Da célula ao executor: o caminho de uma operação DataFrame
O cliente nunca fala com o driver direto: passa pelo plano de controle para pegar URL e token, e depois pelo auth proxy dentro do cluster.
- pyspark[connect] · 3.5.8 (emr-7.14.0)
- SageMaker Unified Studio · notebook gerenciado
- CreateManagedEndpoint · type=SPARK_CONNECT
- GetManagedEndpointSession · Credentials — token
- VPC interface endpoint · AWS PrivateLink
- NLB interno · sub-rede privada
- Auth proxy · x-aws-proxy-auth
- Spark driver · servidor gRPC (pod)
- Executores · dynamicAllocation 3→5
- Amazon S3 · dados + logs do Spark
- Glue Data Catalog · metadados de tabela
Três números para levar à reunião de aprovação
sessionIdleTimeoutInMinutes. É o único freio automático contra driver e executores vivos depois do fim do expediente.IAM é o único controle de acesso — e isso redesenha o namespace
Aqui está a decisão que separa quem migrou com cuidado de quem vai descobrir o problema numa auditoria. Endpoints Spark Connect no EMR on EKS não suportam Lake Formation fine-grained access control e não suportam Trusted Identity Propagation. A documentação é explícita: para impor controle de acesso, use o execution role IAM associado ao endpoint.
Em ambiente com BACEN, PCI-DSS ou LGPD no escopo, isso tem uma leitura direta: o endpoint é a unidade de autorização, não o usuário. Se dez pessoas de dois produtos diferentes compartilham um endpoint, elas compartilham permissão de dado — e o log do CloudTrail vai mostrar o execution role, não quem digitou a query. Rastreabilidade individual você recupera pela sessão (cada uma tem id próprio e roda como pods etiquetados por projeto e usuário), não pela identidade do principal que leu o S3.
A consequência de desenho é a multiplicação de recursos. Como cada security configuration tem relação 1:1 com um virtual cluster, isolar por domínio de dado significa um virtual cluster por domínio, cada um com sua security configuration, seu namespace de sistema e seu execution role. E a política de quem cria endpoint precisa de iam:PassRole com condição iam:PassedToService igual a emr-containers.amazonaws.com — sem essa condição, você acabou de dar à engenharia de dados uma primitiva de escalonamento de privilégio.
Antes e depois, com a terceira coluna que ninguém coloca na tabela
| Livy / JEG (`JUPYTER_ENTERPRISE_GATEWAY`) | Spark Connect (`SPARK_CONNECT`) | Spark local no laptop | |
|---|---|---|---|
| Onde o código é interpretado | Kernel dentro do cluster; o IDE é o do gateway | Cliente local; só o plano lógico vai por gRPC | Tudo local, com dado de amostra que não representa produção |
| Entrada de rede que você passa a operar | Endpoint gerenciado do EMR, sem NLB próprio | NLB interno + VPC interface endpoint, um por cluster EKS | Nenhuma — e nenhum caminho auditável até o dado real |
| Controle de acesso fino ao dado | Caminhos com Lake Formation e propagação de identidade | Apenas execution role IAM: sem FGAC, sem TIP | Credencial pessoal no ~/.aws, o pior dos mundos |
| O que quebra primeiro | Manutenção do EKS mata o kernel no meio da análise | Token expira e a SparkSession precisa ser refeita | O job passa local e falha em escala, na sexta à noite |
O custo que não aparece na planilha do POC
Todo custo é de manutenção, e sessão interativa é a categoria de carga que mais premia o desperdício silencioso. Vale montar a conta antes.
A base já existia: o EMR on EKS cobra uplift sobre o consumo real — US$ 0,01012 por vCPU-hora e US$ 0,00111125 por GB-hora em us-east-1 — sobre o cluster EKS (US$ 0,10/hora) e o EC2 por baixo.
O endpoint do exemplo da documentação — driver com 4 GB, três executores de 2 vCPU e 4 GB, dynamicAllocation até cinco — consome algo como 7 vCPU e 16 GB quando está aberto. Isso é aproximadamente US$ 0,089/hora só de uplift. Em 176 horas úteis por mês, cerca de US$ 15,60 por sessão viva, antes do EC2.
O componente novo é o piso: o NLB interno nasce com o primeiro endpoint e só é removido quando o último virtual cluster session-enabled é apagado. US$ 0,0225/hora são US$ 16,43/mês rodando, com zero sessão conectada, mais NLCU.
O desenho que evita a surpresa é banal e quase ninguém faz: sessionIdleTimeoutInMinutes bem abaixo do padrão de 60 para endpoint de exploração, tag de projeto e usuário obrigatória para atribuir o gasto no Cost Explorer, e um alarme sobre número de endpoints ACTIVE — não sobre a fatura, que chega tarde demais.
Os quatro modos de falha que eu vi na ordem errada
Token expirado é falha de autenticação, não de rede: as chamadas gRPC caem e o time abre ticket de VPC. Versão do cliente divergente dá erro de conexão ou comportamento estranho, e UDF Python com minor diferente falha com PYTHON_VERSION_MISMATCH — nenhum dos dois grita a causa. Security configuration não se apaga antes de todos os endpoints que a usam serem apagados; script de teardown que ignora a ordem trava. O limite de API é baixo onde dói: GetManagedEndpointSessionCredentials tem bucket de 25 com reposição de 1 por segundo, e o teto agregado de todas as APIs do EMR on EKS é 200 com 20/s. Um wrapper que pede token por célula, com vinte pessoas online, encontra throttling antes de encontrar escala.
Anti-padrões
- Um endpoint para toda a engenharia de dados: como a autorização é o execution role do endpoint, endpoint compartilhado é permissão compartilhada — e o CloudTrail registra o role, não a pessoa.
- Tratar Spark Connect como caminho de produção: sessão interativa é para exploração e desenvolvimento incremental. Pipeline agendado continua sendo
StartJobRun, com retry, idempotência e observabilidade de job, não uma sessão que alguém esqueceu aberta. - Manter o padrão de 60 minutos de ociosidade em ambiente de custo controlado: é o valor que faz sentido para o serviço, não para o seu teto de gasto.
- Prometer migração de job RDD: API baseada em RDD não passa pelo Spark Connect. O inventário vem antes do compromisso com data.
- Instalar o AWS Load Balancer Controller às pressas para destravar o endpoint: ele passa a mandar em NLB da sua VPC. Isso é decisão de plataforma, não passo de tutorial.
Leitura pelos pilares do Well-Architected
Segurança
O endpoint é a fronteira de autorização: sem Lake Formation FGAC e sem Trusted Identity Propagation, o execution role define tudo. Restrinja a política a arn:aws:emr-containers:...:/virtualclusters/<id>/endpoints/* e exija iam:PassedToService igual a emr-containers.amazonaws.com no iam:PassRole. O gRPC nunca sai da VPC — NLB interno em sub-rede privada com PrivateLink na frente.
Confiabilidade
O primeiro endpoint de cada cluster EKS demora minutos a mais porque provisiona NLB e VPC endpoint; trate isso como passo de bootstrap, não como latência de uso. Token expirado exige SparkSession nova, então o cliente precisa de renovação automática antes de ganhar usuário.
Se eu fosse fazer essa migração numa plataforma financeira, começaria por um único domínio de dado — um virtual cluster novo, session-enabled, com execution role que só lê o bucket daquele domínio — e deixaria o caminho Livy de pé em paralelo por um trimestre. Não é medo de tecnologia nova; é que a ausência de Lake Formation FGAC muda o desenho de isolamento, e esse tipo de mudança não se descobre em POC de duas semanas. A lição que eu já paguei: capacidade nova de exploração sempre vira consumo permanente, então eu entrego o endpoint junto com o timeout curto e o painel de gasto por tag no mesmo dia — acrescentar controle depois de o time se acostumar ao conforto é uma conversa muito pior. E manteria produção em StartJobRun, sem exceção, porque a sessão interativa é excelente para descobrir a resposta e péssima para repeti-la todos os dias.
Referências
Veredito
Migre — para exploração, com escopo estreito e data marcada de revisão. O Spark Connect no EMR on EKS resolve um problema real e antigo: o desenvolvedor volta a usar o IDE dele, com breakpoint, sobre dado de escala de produção, e o driver continua dentro do cluster que a plataforma já opera e já monitora. Vale o esforço quando três condições estão juntas: o acervo é DataFrame e SQL em PySpark, o controle de acesso por execution role é suficiente para o seu regime regulatório, e existe alguém responsável por apagar endpoint ocioso. Falhando qualquer uma das três, espere: sem FGAC e sem propagação de identidade, um endpoint compartilhado entre domínios de dado é um achado de auditoria esperando a data. E em nenhum cenário isso substitui StartJobRun em produção — o ganho aqui é no ciclo de descoberta, não no de execução.
Deep dives de arquitetura, AWS, IA e mercado — direto no seu email. Grátis.
Sem spam · cancele quando quiser
Pergunte ao Fernando sobre isto
Receba uma resposta focada sobre este artigo do meu assistente de IA, baseada no meu trabalho.
Participe da conversa
Entre para comentar
Confirme seu e-mail para participar — você também recebe a newsletter. Sem senha.
Continue lendo
Inteligência de arquitetura, na sua caixa de entrada
Sinais curados e análises originais sobre AWS, IA, sistemas distribuídos e mercado — do jeito que um arquiteto de soluções lê.
- Curadoria de AWS · IA · arquitetura · mercado
- Novos estudos de arquitetura e deep-dives quando saem
- Sínteses diretas — profundidade sem ruído
- Sem spam · double opt-in · cancele quando quiser