Apache Spark
Plataforma de Computação Distribuída

Com a evolução das redes de computadores, um novo paradigma computacional surgiu e tornou-se 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.
Este 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.

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 ajudaram na sua implementação, e uma vasta comunidade com mais de 1.200 desenvolvedores de centenas de organizações continuam a contribuir para o seu contínuo detalhamento.
É usado por organizações em vários setores e a 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 planeador 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, treino de modelos para aprendizagem automática e IA.
Adicionalmente, o Spark executa uma pilha de bibliotecas nativas de aprendizagem automática e processamento de grafos e estruturas de dados semelhantes a SQL, permitindo um desempenho excecional.
Conta com mais de 80 operadores de alto nível, facilitando a criação de aplicações paralelos.
O Spark partilha 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 aprendizagem automática 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 as suas funcionalidades e disponibiliza ferramentas adicionais, como a implementação de aplicações num cluster Hadoop (com SIMR - Spark Inside MapReduce) ou YARN.

Arquitetura do Apache Spark
O Apache Spark é um mecanismo de processamento distribuído que opera no princípio de coordenador/trabalhador.
A sua arquitetura consiste nos seguintes componentes principais:
-
Spark Driver: É o mestre da arquitetura Spark. É a aplicação principal que gere 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.

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 ficheiros tradicional, no HDFS e em algumas bases de dados NoSQL, como o HBase.
-
Operações: Representam transformações (agrupamentos, filtros, mapeamento de dados) ou ações (contagens e persistências) realizadas num RDD. Um programa Spark normalmente é definido como uma sequência de transformações ou ações realizadas num conjunto de dados.
-
Spark Context: O contexto é o objeto que conecta o Spark ao programa que está a ser desenvolvido. Pode ser acedido como uma variável num programa.
Bibliotecas do Apache Spark
Além das APIs, existem bibliotecas que compõem o seu ecossistema e disponibilizam 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 dados em tempo real. É escalável, possui alto throughput, é tolerante a falhas e suporta workloads
em lote
oustreaming
. O Spark Streaming permite a leitura/escrita 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. Isto 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 Bases de dados), transformá-los e expô-los para consultas ad-hoc.
-
Spark MLlib: A biblioteca de aprendizagem automática 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 Partilhadas: O Spark oferece dois tipos de variáveis partilhadas para torná-lo mais eficiente na execução em clusters:
-
Broadcast: São variáveis apenas de 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 partilhadas 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
O seu ciclo de vida envolve vários passos intermédios, cada um responsável por conduzir responsabilidades específicas.
- O processo começa 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 da aplicação.
- O programa driver solicita recursos do cluster manager para iniciar os executores com base na configuração da aplicação.
- O cluster manager ativa o executor no nó worker em nome do driver Spark, que agora assume a propriedade do ciclo de vida da aplicação.
- 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.

Outras Características do Apache Spark
- O Spark pode aceder a 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 dados em modo distribuído.
- Oferece um mecanismo otimizado com suporte a grafos 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. Estas 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 ficheiro de saída, e outro job do Spark consome-o, faz alguns cálculos e grava novamente em algum ficheiro de saída. Nesse cenário, usar um formato de ficheiro serializado, como Parquet, dá-nos uma vantagem significativa sobre os formatos CSV e JSON.
-
Evitando Funções Definidas pelo Utilizador: 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. Desta 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 intermédio repetidamente para cálculos adicionais, o Spark disponibiliza um recurso para armazenar um DF específico na memória na forma dum cache.
Detalhes do Projeto Apache Spark
O Spark é escrito na linguagem Scala e executado numa máquina virtual Java. Atualmente, suporta as seguintes linguagens para desenvolvimento de aplicações:
- Scala
- Java
- Python
- Clojure
- R
