Saltar para o conteúdo principal

Apache Spark

Plataforma de Computação Distribuída

Apache Spark icon

Com a evolução das redes de computadores, um novo paradigma computacional surgiu e se tornou extremamente poderoso: a possibilidade de distribuição do processamento entre computadores diferentes.

A computação distribuída permite a repartição e especialização das tarefas computacionais, segundo a natureza e função de cada computador.

Esse paradigma surgiu para solucionar um grande problema da computação, que é a necessidade de computadores com poder de processamento suficiente para realizar a análise do grande volume de dados disponível atualmente.

Computação Distribuída
Computação Distribuída

Características do Apache Spark

O Apache Spark é um mecanismo de análise unificada para processamento de dados em larga escala em computação distribuída.

Criado em 2009 na Universidade da Califórnia pelo AMPLab de Berkeley, o Spark rapidamente ganhou uma grande comunidade, levando à sua adoção pela Apache Software Foundation em 2013.

Desenvolvedores de mais de 300 empresas auxiliaram na sua implementação, e uma vasta comunidade com mais de 1.200 desenvolvedores de centenas de organizações continuam a contribuir para seu contínuo refinamento.

É usado por organizações em uma gama de setores e sua comunidade de desenvolvedores é uma das maiores existentes.

O poder do Spark vem do seu processamento em memória (in-memory).

Ele usa um conjunto distribuído de nós com muita memória e codificação de dados compacta, juntamente com um planejador de consultas (query planner) otimizado para minimizar o tempo de execução e a demanda por memória.

Como realiza cálculos em memória (in-memory), pode processar até 100 vezes mais rápido do que as estruturas que processam no disco.

É ideal para processar grandes volumes de dados em Analytics, treinamento de modelos para aprendizado de máquina e IA.

Adicionalmente, o Spark executa uma pilha de bibliotecas nativas de aprendizado de máquina e processamento de gráficos e estruturas de dados semelhantes a SQL, permitindo um desempenho excepcional.

Conta com mais de 80 operadores de alto nível, facilitando a criação de aplicativos paralelos.

O Spark guarda algumas semelhanças com o Hadoop. Ambos são estruturas de código aberto para processamento de dados analíticos, vivem na Apache Software Foundation, contêm bibliotecas de aprendizado de máquina e podem ser programados em várias linguagens diferentes.

No entanto, o Spark estende o número de cálculos possíveis com o Hadoop, aprimorando o componente de processamento de dados nativo do Hadoop, o MapReduce.

O Spark usa a infraestrutura do Hadoop Distributed File System (HDFS), mas melhora suas funcionalidades e fornece ferramentas adicionais, como a implementação de aplicativos em um cluster Hadoop (com SIMR - Spark Inside MapReduce) ou YARN.

Interface Apache Spark
Interface Apache Spark

Arquitetura do Apache Spark

O Apache Spark é um mecanismo de processamento distribuído que opera no princípio de coordenador/trabalhador.

Sua arquitetura consiste nos seguintes componentes principais:

  • Spark Driver: É o mestre da arquitetura Spark. É a aplicação principal que gerencia a criação e execução do processamento definido pelo programador.

  • Cluster Manager: Um componente opcional necessário apenas se o Spark for executado de forma distribuída. Ele é responsável por gerenciar as máquinas que serão usadas como trabalhadores (workers).

  • Spark Workers: São as máquinas que executam efetivamente as tarefas enviadas pelo programa Driver. Se o Spark for executado de forma local, a máquina pode desempenhar tanto o papel de Driver quanto de Worker.

Arquitetura Spark
Arquitetura Spark

Componentes Fundamentais do Modelo de Programação Spark

  • Resilient Distributed Datasets (RDD): O principal objeto do modelo de programação Spark. É nesses objetos que os dados são processados. Eles armazenam os dados na memória para realizar várias operações como carregamento, transformação e ações (cálculos, gravações, filtros, uniões e map-reduce) nos dados. Abstraem um conjunto de objetos distribuídos no cluster, geralmente executados na memória principal. Podem estar armazenados em sistemas de arquivo tradicional, no HDFS e em alguns bancos de dados NoSQL, como o HBase.

  • Operações: Representam transformações (agrupamentos, filtros, mapeamento de dados) ou ações (contagens e persistências) realizadas em um RDD. Um programa Spark normalmente é definido como uma sequência de transformações ou ações realizadas em um conjunto de dados.

  • Spark Context: O contexto é o objeto que conecta o Spark ao programa que está sendo desenvolvido. Pode ser acessado como uma variável em um programa.

Bibliotecas do Apache Spark

Além das APIs, existem bibliotecas que compõem seu ecossistema e fornecem capacidades adicionais:

  • Spark Streaming: Pode ser usado para processar dados de streaming em tempo real com base na computação de microbatch. Para isso, utiliza o DStream, que é basicamente uma série de RDDs para processar os dados em tempo real. É escalável, possui alto throughput, tolerante a falhas e suporta workloads batch ou streaming. O Spark Streaming permite a leitura/gravação a partir/para tópicos Kafka nos formatos texto, csv, avro e json.

  • Spark SQL: Fornece a capacidade de expor os conjuntos de dados Spark por meio de uma API JDBC. Isso permite a execução de consultas no estilo SQL sobre esses dados, fazendo uso de ferramentas tradicionais de BI e visualização. Além disso, permite a utilização de ETL para extração de dados em diferentes formatos (Json, Parquet ou Banco de dados), transformá-los e expô-los para consultas ad-hoc.

  • Spark MLlib: A biblioteca de aprendizagem de máquina do Spark, que consiste em algoritmos de aprendizagem, incluindo classificação, regressão, clustering, filtragem colaborativa e redução de dimensionalidade.

  • Spark GraphX: Uma nova API do Spark para grafos e computação paralela. Simplificando, estende os RDDs do Spark para grafos. Para apoiar a computação de grafos, expõe um conjunto de operadores fundamentais (subgrafos e vértices adjacentes), bem como uma variante otimizada do Pregel. Além disso, inclui uma crescente coleção de algoritmos para simplificar tarefas de análise de grafos.

  • Variáveis Compartilhadas: O Spark oferece dois tipos de variáveis compartilhadas para torná-lo mais eficiente na execução em clusters:

    • Broadcast: São variáveis somente leitura (read-only) que são armazenadas em cache em todos os nós do cluster para acesso ou uso por tarefas. Em vez de enviar os dados junto com cada tarefa, o Spark distribui as variáveis de transmissão (broadcast) na máquina usando algoritmos eficientes de transmissão para reduzir os custos de comunicação.

    • Accumulator (Acumuladoras): São variáveis compartilhadas apenas adicionadas por meio de uma operação associativa e comutativa, usadas para executar contadores (similar aos contadores MapReduce) ou operações de soma.

Fluxo de Trabalho do Apache Spark

Seu ciclo de vida envolve vários passos intermediários, cada um responsável por conduzir responsabilidades específicas.

  • O processo se inicia com a submissão do job pelo cliente, por meio da opção spark-submit.
  • A classe main, especificada durante a submissão do job, é chamada e o programa Spark driver é iniciado no nó master, responsável por gerenciar o ciclo de vida do aplicativo.
  • O programa driver solicita recursos do cluster manager para iniciar os executores com base na configuração do aplicativo.
  • O cluster manager ativa o executor no nó worker em nome do driver Spark, que agora assume a propriedade do ciclo de vida do aplicativo.
  • O driver Spark cria uma DAG com base no RDD. A tarefa é então dividida em etapas. O driver Spark envia as tarefas para o executor, que as executa.
  • O executor envia uma solicitação de conclusão da tarefa ao driver por meio do cluster manager. Depois que todas as tarefas são concluídas em todos os executores, o driver envia um status de conclusão ao cluster manager.
Fluxo Spark
Fluxo Spark

Outras Características do Apache Spark

  • O Spark pode acessar fontes de dados variáveis e executar em várias plataformas, incluindo o Hadoop.
  • Fornece APIs funcionais de alto nível em Java, Scala, Python e R para:
    • manipulação de dados em grande escala
    • armazenamento em cache de dados in-memory
    • reutilização de datasets
  • Suporta vários formatos e conjuntos de APIs para lidar com qualquer tipo de dado em modo distribuído.
  • Oferece um mecanismo otimizado com suporte a gráficos de execução geral.
  • Utiliza o conceito de grafo acíclico direcionado (DAG), por meio do qual é possível desenvolver pipelines compostos por várias etapas complexas.
  • A capacidade de armazenamento de dados in-memory e processamento near real-time torna o Spark mais rápido que o framework MapReduce e oferece uma vantagem para casos de uso iterativos onde o mesmo dataset é usado várias vezes em diferentes execuções.

Boas Práticas para Apache Spark

  • Uso de Dataframe/Dataset sobre RDD: O RDD serializa e desserializa sempre que distribui os dados entre clusters. Essas operações são muito caras. Por outro lado, o Dataframe armazena os dados como binários, usando armazenamento off-heap, sem a necessidade de serialização e desserialização de dados na distribuição para clusters, tornando-se uma grande vantagem em relação ao RDD.

  • Uso do Coalesce para Reduzir o Número de Partições: Sempre que for necessário reduzir o número de partições, use o coalesce, pois ele faz o movimento mínimo de dados sobre a partição. Por outro lado, o repartition recria toda a partição, tornando a movimentação de dados muito alta. Para aumentar o número de partições, temos que usar o repartition.

  • Uso de Formatos de Dados Serializados: Geralmente, seja um job de streaming ou em lote, o Spark grava os resultados calculados em algum arquivo de saída, e outro job do Spark o consome, faz alguns cálculos e grava novamente em algum arquivo de saída. Nesse cenário, usar um formato de arquivo serializado, como Parquet, nos dá uma vantagem significativa sobre os formatos CSV e JSON.

  • Evitando Funções Definidas pelo Usuário: Use as funções pré-construídas do Spark sempre que possível. As funções UDF (User Defined Functions) são uma caixa preta para o Spark, impedindo-o de aplicar otimizações. Dessa forma, perdemos todos os recursos de otimização oferecidos pelo Dataframe/Dataset do Spark.

  • Dados de Memória em Cache: Sempre que fazemos uma sequência de transformações do Dataframe e precisamos usar um Dataframe intermediário repetidamente para cálculos adicionais, o Spark fornece um recurso para armazenar um DF específico na memória na forma de um cache.

Detalhes do Projeto Apache Spark

O Spark é escrito na linguagem Scala e executado em uma máquina virtual Java. Atualmente, suporta as seguintes linguagens para desenvolvimento de aplicativos:

  • Scala
  • Java
  • Python
  • Clojure
  • R
Linguagens do Spark
Linguagens do Spark

Fontes