Apache Spark

Redes de Computadores I - 24.1

Trabalho desenvolvido pelos alunos da Universidade Federal do Rio de Janeiro:

  • Lucas Garcia Santiago de Abreu
  • Matheus Henrique Sant'Anna Cardoso
  • Vinícius Quintanilha Porto Gomes

1. Introdução

A área de análise de Big Data é repleta de pesquisas e desafios. Ao longo dos anos, torna-se emergente a necessidade por inovações na área em diversos campos da indústria.

Sendo assim, é essencial um framework desenhado especificamente para lidar com as requisições impostas por dados cada vez mais massivos para preencher as necessidades de velocidade, armazenamento e executar da melhor forma possível os algorítmos pelos quais essas imensas massas de dados serão submetidos.

Dessa forma, o Apache Spark surge como uma ferramenta que introduziu uma nova abordagem para ciência e engenharia de dados, na qual um único motor (engine) é necessário podendo ser utilizado em diversas linguagens de alto nível, como Java, Python, SQL, entre outras.

Essa versatilidade garantiu ao Spark uma plena adoção tanto na indústria quanto na academia e, hoje, é utilizada em projetos open source em algumas iniciativas da Apache Sofware Foundation.

Dada a sua importância e às interessantes formas como esta ferramenta resolve alguns problemas da computação com soluções que incluem processamento distribuído e em memória, é crucial a abordagem dela em um curso atual de Redes de Computadores.

1.1. O que é o Apache Spark?

Com o projeto sendo iniciado em 2009 por Matei Zaharia e, após ter sido doado para a Apache Software Foundation em 2013 (possuia a licença BSD desde 2010), vários pesquisadores contribuíram para com a ferramenta buscando a melhoria de seu núcleo (core) e suas bibliotecas de mais alto nível.

Ao todo, o sistema do Apache Spark consistem em diversos componentes dos quais constam, além de seu próprio núcleo, várias bibliotecas de mais alto nível que permitem executar os algorítmos de aprendizado de máquina ou busca e mineração de dados.

Dessas bibliotecas, podemos citar:

  • Spark's MLlib: Para aprendizado de máquina
  • GraphX: Para análise de Grafos
  • Spark Streaming: Para processamento de stream
  • Spark SQL: Para processamento de dads estruturados

Com um núcleo independente e tais bibliotecas já desenvolvidas por debaixo dos panos, o Spark mostra uma de duas vantagens que é a possibilidade do uso de diversas linguagens de programação de alto nível oferecendo uma interface simples para programação com pipelines de dados em larga escala.

A principal ferramenta está na forma em como o Spark lida com os dados, ou seja, a abstração feita para os dados, com a utilização dos Datasets Distribuídos, ou Resilient Distributed Datased (RDD) sobre o qual falaremos mais a frente.

1.1.1. Definição de Processamento Distribuído

É de suma importância que passemos pelo tópico de processamento distribuído ainda que seja apenas para definí-lo. Isso se dá pela sua relevância, não apenas na ferramenta em si da qual se trata este trabalho, mas do contexto de processamento de dados e Big Data como um todo. Sendo assim, uma breve síntese.

O processamento distribuído é um paradigma de computação no qual tarefas computacionais são executadas em múltiplos dispositivos ou computadores interconectados em uma rede, chamados de nós. Logo, ao invés de depender de uma única máquina para o processamento de grandes volumes de dados, o trabalho é distribuído entre esses diversos nós permitindo a paralelização das operações.

Imagem ilustrativa Fonte: distributed computing em TechTarget.

Além disso, permite, por natureza, gerar um ecossistema mais tolerante a falhas por conta da redundância.

Seu funcionamento pode se dar através de memória compartilhada, passagem de mensagem (ou ambos) em que, normalmente, um controlador central define tarefas para as diversas máquinas na rede que, trabalhando de forma independente, enviam o resultado final ao coordenador central, o qual combina os resultados e gera uma saída final.

O objetivo do processamento distribuído é aumentar a capacidade de processamento e melhorar o desempenho geral, permitindo que grandes volumes de dados sejam processados de forma mais eficiente e rápida, além de gerar sistemas mais tolerantes à falhas.

1.1.2. Importância no processamento de grandes volumes de dados

É sabido que a quantidade de dados no planeta avança a passos largos. Dentro de empresas, não é diferente. Nisso, para reduzir custos e otimizar decisões, o processamento de Big Data é fundamental.

Já foi dito que o Apache Spark possui adoção na indústria e na academia. Isso se deve ao fato de ser necessária a análise de dados para políticas públicas e ciência de uma forma geral, seja em decifrar o código genético do coronavírus ou analisar as linhas de transporte de uma cidade, os dados estão em todos os campos.

1.2. De início, com Apache Hadoop

O Apache Hadoop é um framework de código aberto projetado para o armazenamento e processamento distribuído de grandes volumes de dados em clusters de computadores. Utilizando modelos de programação simples, ele permite que essas tarefas sejam realizadas de forma eficiente. O Hadoop é escalável, podendo ser expandido de um único computador para milhares de máquinas em um cluster, com cada uma delas fornecendo computação e armazenamento local. Dessa maneira, o Hadoop é capaz de gerenciar e processar grandes conjuntos de dados, que podem variar de gigabytes a petabytes.

O framework principal do Hadoop é composto por quatro módulos que, juntos, formam o ecossistema Hadoop:

  • Hadoop Distributed File System (HDFS): Sendo o componente central do ecossistema, o HDFS é um sistema de arquivos distribuído que permite acesso de alta capacidade aos dados do aplicativo, sem a necessidade de definir esquemas antecipadamente.
  • Yet Another Resource Negotiator (YARN): O YARN é uma plataforma de gerenciamento de recursos que coordena os recursos de computação em clusters e os utiliza para agendar os aplicativos dos usuários, realizando a programação e alocação de recursos em todo o sistema Hadoop.
  • Hadoop Common: Inclui as bibliotecas e utilitários que são utilizados e compartilhados pelos demais módulos do Hadoop.
  • MapReduce: Este é um modelo de programação voltado para o processamento de grandes volumes de dados. Utilizando algoritmos de computação distribuída e paralela, o MapReduce facilita a transferência da lógica de processamento, permitindo a criação de aplicativos que transformam grandes conjuntos de dados em conjuntos mais gerenciáveis.

A plataforma funciona distribuindo jobs de big data e análise do Hadoop entre nós em um cluster de compute, dividindo-os em workloads menores que podem ser executados em paralelo.

Todos os módulos do Hadoop são desenvolvidos com a premissa básica de que falhas de hardware em máquinas individuais ou em racks de máquinas são eventos comuns e devem ser gerenciados automaticamente pelo framework de software.

Claramente o MapReduce é o módulo mais atraente (pelo menos para os fins que estamos tratando aqui) para o quesito de análide de grandes volumes de dados. Não é a toa que é este o predecessor do Apache Spark.

De forma geral, o Apache Hadoop já resolve algumas necessidades no quesito de Sistemas Distribuídos. Sua componente mais promissora com relação aos dados será mais discutida no próximo tópico.

Problemas com Apache Hadoop

No entanto, as arquiteturas Hadoop enfrentam diversos desafios, especialmente ao longo do tempo. O Hadoop pode ser excessivamente complexo, demandando recursos e conhecimento significativos para sua configuração, manutenção e atualizações. Além disso, é demorado e ineficiente devido às frequentes leituras e gravações necessárias para realizar cálculos.

1.3. Hadoop MapReduce

A estrutura do Framework funciona da seguinte forma:

  • Divisão e distribuição dos dados: os dados são divididos em blocos menores chamados de "splits". Cada split é então distribuído para os nós do cluster de computadores.
  • Fase de Map: uma função definida pelo usuário chamada de função "map" é aplicada a cada split de dados. Esta função produz uma lista de pares chave-valor intermediários.
  • Ordenação e Particionamento: os pares chave-valor intermediários são particionados e agrupados com base na chave. Esses pares são ordenados para garantir que todas as ocorrências da mesma chave estejam agrupadas juntas.
  • Fase de Shuffle e Sort: os pares chave-valor intermediários são transferidos entre os nós do cluster para que todos os valores associados à mesma chave estejam disponíveis em um único nó.
  • Fase de Reduce: uma função definida pelo usuário chamada de função "reduce" é aplicada a cada chave única e à lista de valores associados a essa chave. Esta função pode realizar operações de agregação, filtragem ou outras operações definidas pelo usuário.
  • Saída: os resultados da redução são escritos em arquivos de saída.

A questão aqui é que, após as operações, o MapReduce persiste os dados no disco, o que pode acarretar em perdas de performance significativas.

Por mais que o processamento distribuído já paralelize as operações, é necessário que as decisões e os processos (como executar algorítmos de aprendizado de máquina) sejam mais eficazes dado uma grande quantidade de dados.

2. Gerenciamento Distribuído

O gerenciamento distribuído é essencial para processar grandes volumes de dados, utilizando múltiplas máquinas de forma coordenada para melhorar o desempenho e a resiliência do sistema.

Distribuição de Tarefas: O trabalho é dividido entre diferentes máquinas (nós) para evitar sobrecarga em uma única máquina e garantir que todas contribuam para o processamento.

Comunicação Entre Nós: As máquinas comunicam-se via passagem de mensagens ou memória compartilhada para trabalhar de forma sincronizada e eficiente, reduzindo a latência.

Tolerância a Falhas: O sistema deve continuar operando mesmo se algumas máquinas falharem. Isso é feito por meio da replicação de dados e tarefas, garantindo que outros nós possam assumir funções sem interrupção.

Monitoramento e Ajuste: O desempenho do sistema é continuamente monitorado e ajustado para garantir eficiência e confiabilidade. Métricas de desempenho e análise de logs são usadas para otimizar a operação.

2.1 De Hadoop MapReduce para Apache Spark

A transição histórica de Hadoop MapReduce para Apache Spark marca uma evolução significativa na maneira como grandes volumes de dados são processados e analisados. Inicialmente, Hadoop MapReduce dominou o cenário de big data desde seu lançamento em 2006, oferecendo uma solução robusta para o processamento distribuído de dados em clusters de computadores. No entanto, a necessidade de melhorar a velocidade e a eficiência do processamento levou ao desenvolvimento do Apache Spark.

Desenvolvimento do Apache Spark: Em 2009, Matei Zaharia e sua equipe na Universidade da Califórnia, Berkeley, iniciaram o projeto Apache Spark para superar as limitações do MapReduce. Eles desenvolveram uma nova abordagem de processamento em memória, que reduzia drasticamente o tempo de execução das tarefas. Em 2013, o Spark foi doado à Apache Software Foundation, onde rapidamente ganhou popularidade devido ao seu desempenho superior e flexibilidade.

Adoção na Indústria: Empresas começaram a adotar o Spark para melhorar suas operações de big data. Sua capacidade de processar dados até 100 vezes mais rápido que o Hadoop MapReduce em memória, e até 10 vezes mais rápido em disco, foi um grande atrativo. Além disso, a API amigável do Spark, suportando várias linguagens de programação, tornou-o acessível para um público mais amplo de desenvolvedores.

Impacto Acadêmico e Industrial: A academia também reconheceu o potencial do Spark, com muitas pesquisas focadas em melhorar e expandir suas capacidades. A indústria beneficiou-se enormemente, com empresas de tecnologia, finanças, saúde e muitas outras áreas implementando Spark para análise de dados, aprendizado de máquina, processamento de streaming e muito mais.

2.2 Directed Acyclic Graph (DAG)

O Directed Acyclic Graph (DAG) é uma estrutura fundamental no Apache Spark, que representa um avanço significativo em relação ao modelo de MapReduce. O DAG permite que Spark realize otimizações avançadas e maximize a eficiência do processamento de dados.

Definição de DAG: Um DAG é uma estrutura de dados em forma de gráfico onde os nós representam operações de computação e as arestas representam a dependência de dados entre essas operações. O termo "acyclic" indica que o gráfico não possui ciclos, ou seja, não é possível retornar ao mesmo nó através de um caminho diferente.

Funcionamento no Spark: No Spark, quando uma operação é submetida, o sistema cria um DAG que descreve todas as etapas necessárias para completar essa operação. Em vez de processar cada etapa sequencialmente e gravar no disco após cada operação, como no MapReduce, Spark executa uma série de transformações em memória, seguindo as dependências especificadas pelo DAG.

Vantagens do DAG:

  • Otimização de Tarefas: O DAG permite que o Spark otimize o plano de execução globalmente, em vez de em cada etapa individualmente. Isso resulta em menos operações de leitura e gravação em disco, reduzindo o tempo de processamento.
  • Resiliência: Em caso de falha de um nó, o Spark pode recomputar apenas as partes afetadas do DAG, utilizando os dados intermediários armazenados em memória, sem precisar reiniciar todo o processo.
  • Eficiência: Com o DAG, o Spark pode executar operações em paralelo sempre que possível, aproveitando ao máximo os recursos do cluster.

Exemplo de Uso do DAG: Imagine um processo de análise de dados que envolve várias etapas, como filtragem, mapeamento e redução. No Spark, essas etapas são representadas como um DAG, onde cada operação depende dos resultados das operações anteriores. O Spark analisa esse DAG e identifica as oportunidades para executar operações em paralelo e minimizar as operações de I/O.

Comparação com MapReduce: Diferentemente do MapReduce, que processa dados em etapas discretas e grava no disco entre cada etapa, o DAG do Spark permite que as operações sejam encadeadas e processadas em memória. Isso não apenas acelera o processamento, mas também simplifica a programação, já que os desenvolvedores podem escrever seus algoritmos como um fluxo de transformações em vez de uma série de tarefas independentes.

Em resumo, o Directed Acyclic Graph (DAG) é um componente crucial que permite ao Apache Spark realizar otimizações avançadas, melhorar a eficiência e a resiliência do processamento de dados. A utilização do DAG marca uma grande melhoria em relação ao modelo de MapReduce, permitindo que o Spark ofereça um desempenho superior e uma experiência de desenvolvimento mais intuitiva.

3. Dados Distribuídos e Paralelização de Operações

Chegamos ao momento no qual lidamos com as estruturas que permitem o funcionamento do Spark. Estudar a forma como os dados ficam distribuídos é primordial.

O Apache Spark apresenta várias abstrações importantes para a representação de dados e a gestão da computação. Nos níveis mais básicos, os dados são representados por Conjuntos de Dados Distribuídos Resilientes (RDDs) e as operações sobre esses RDDs são classificadas como transformações ou ações. Além disso, o Spark inclui variáveis de broadcast e acumuladores, que permitem o compartilhamento de variáveis em um cluster de computação.

3.1. Resilient Distributed Dataset (RDD)

O conceito central do Spark é o conjunto de dados distribuído resiliente (RDD), uma coleção de elementos que é tolerante a falhas e pode ser manipulada em paralelo. Existem duas formas de criar RDDs: uma é paralelizando uma coleção já existente no seu programa driver; a outra é referenciando um conjunto de dados em um sistema de armazenamento externo, como um sistema de arquivos compartilhado, HDFS, HBase ou qualquer fonte de dados que suporte Hadoop InputFormat.

Avaliação tardia de RDDs: as transformações em RDDs são avaliadas de maneira tardia, ou seja, o Spark só computa os RDDs quando uma ação é executada. O Spark rastreia o grafo de dependências das transformações, que é utilizado para calcular cada RDD sob demanda e recuperar dados perdidos (imagem adaptada de: http://www.slideshare.net/GirishKhanzode/apache-spark-core )

Sendo uma abstração de memória distribuída tolerante a falhas, o RDD evita a replicação de dados ao manter um grafo das operações que o construíram. Isso permite recomputar de forma eficiente os dados perdidos em caso de falhas. As partições de um RDD podem ser gerenciadas para garantir consistência ao longo das iterações, permitindo ao núcleo do Spark coparticionar RDDs e agendar tarefas de maneira coordenada para evitar a movimentação de dados. Para evitar a recomputação, os RDDs devem ser explicitamente armazenados em cache quando a aplicação precisa reutilizá-los várias vezes.

3.2. Dataframes e Datasets

De fato, o Spark é construído sobre a API do RDD. Diversas melhorias foram-lhe impostas, inclusive as que se tratavam sobre as abstrações de dados, gerando melhores formas de como realizar essas abstrações.

É mais comum, principalmente em aplicações web, que os dados estejam estruturados em tabelas em um modelo relacional. A principal ferramenta é um banco de dados como Postgres, MySQL, SQLServer, entre tantos outros. Além disso, parte da ferramenta de análise de dados é o SQL, sendo uma linguagem muito útil para lidar com dados.

Pensando nesses tipos de dados estruturados, foi introduzido a API DataFrame, parte do Spark SQL. Um DataFrame funciona como uma tabela em um banco de dados relacional ou como um data frame no R/Python, mas com as otimizações avançadas do Spark, que avalia as transformações de maneira preguiçosa. Assim como os RDDs, é uma coleção distribuída de dados, mas organizada em colunas nomeadas (ou seja, uma coleção de registros estruturados). Isso fornece ao Spark mais informações sobre a estrutura dos dados e das operações, possibilitando otimizações adicionais.

Embora a API RDD seja versátil, ela oferece poucas oportunidades para otimizações automáticas devido à falta de informações sobre a estrutura dos dados e a semântica das funções do usuário. Por outro lado, a API DataFrame permite realizar operações relacionais em RDDs e fontes de dados externas, facilitando uma integração rica entre operações relacionais e funcionais em aplicações Spark. Atualmente, os DataFrames são a principal forma de representação de dados na API de Pipelines de ML do Spark. Outras bibliotecas do Spark, como o GraphFrames para o GraphX, também começaram a se integrar ao Spark SQL via API DataFrame.

Outra melhoria significativa é a API Dataset, uma interface experimental introduzida no Spark 1.6. Esta API é uma extensão da API DataFrame, oferecendo uma interface de programação orientada a objetos com verificação de tipos. Um Dataset é uma coleção imutável e fortemente tipada de objetos mapeados para um esquema relacional. O objetivo é combinar os benefícios dos RDDs com as vantagens do mecanismo de execução otimizado do Spark SQL (ou seja, o otimizador Catalyst) e a rápida codificação na memória do Tungsten.

Abaixo, um exemplo de uso do DataFrame.

Sua API é, de fato, muito simples. Abaixo, um link para exemplos, de onte a figura acima foi retirada.

Exemplos -- Spark Dataframe

3.3. Variáveis Compartilhadas

Embora o Spark utilize uma arquitetura 'shared-nothing', sem um espaço de memória global compartilhado entre o programa driver e as tarefas, ele oferece suporte a dois tipos de variáveis compartilhadas para casos de uso específicos: variáveis de broadcast e acumuladores.

As variáveis de broadcast são usadas para manter variáveis de leitura em cache em cada máquina, como uma cópia de um grande conjunto de dados de entrada, evitando a necessidade de enviar uma cópia com cada tarefa. Por outro lado, os acumuladores são variáveis às quais os workers podem adicionar valores apenas através de operações associativas, sendo que o driver pode apenas ler esses valores. Eles são úteis para implementar contadores ou somas.

3.4. Transformações e Ações

Além da abstração dos RDDs, o Spark oferece uma coleção de operações paralelas: transformações e ações.

As transformações são operações determinísticas e lazy, que definem um novo RDD sem computá-lo de imediato. Com uma transformação estreita (como map, filter, etc.), cada partição do RDD pai é utilizada por no máximo uma partição do RDD filho. Em contrapartida, várias partições filhas podem depender da mesma partição do RDD pai devido a transformações amplas (como join, groupByKey, etc.).

Uma ação (como count, first, take, etc.) inicia a computação em um RDD e retorna os resultados para o programa driver ou os escreve em um armazenamento externo. As transformações são executadas apenas quando uma ação é chamada. Nesse momento, o Spark divide a computação em tarefas que são executadas em paralelo em máquinas diferentes. Cada máquina realiza tanto sua parte das transformações quanto a ação chamada, retornando apenas sua resposta ao programa driver. Com transformações e ações, as computações podem ser organizadas em várias etapas de um pipeline de processamento, sendo essas etapas separadas por operações de shuffle distribuídas para redistribuição de dados.

3.5. Arquitetura do Apache Spark

Gerenciadores de Cluster e Fontes de Dados

Um gerenciador de cluster é utilizado para obter recursos do cluster para a execução de jobs. O núcleo do Spark pode operar sobre diversos gerenciadores de cluster, como Hadoop YARN, Apache Mesos, Amazon EC2 e o gerenciador de cluster nativo do Spark (standalone). O gerenciador de cluster é responsável por gerenciar o compartilhamento de recursos entre as aplicações Spark. Além disso, o Spark pode acessar dados armazenados no HDFS, Cassandra, HBase, Hive, Alluxio e qualquer fonte de dados compatível com Hadoop.

Figura retirada da documentação do Apache Spark.

Aplicações Spark

Executar uma aplicação Spark envolve cinco entidades principais: o programa driver, o gerenciador de cluster, os workers, os executores e as tarefas. O programa driver é uma aplicação que usa o Spark como uma biblioteca e define o fluxo de controle de alto nível da computação desejada. Enquanto um worker fornece recursos de CPU, memória e armazenamento para uma aplicação Spark, um executor é um processo JVM (Java Virtual Machine) que o Spark cria em cada worker para essa aplicação. Um job é um conjunto de computações (como um algoritmo de processamento de dados) que o Spark executa em um cluster para fornecer resultados ao programa driver. Uma aplicação Spark pode lançar múltiplos jobs. O Spark divide um job em um gráfico acíclico direcionado (DAG) de estágios, onde cada estágio é uma coleção de tarefas. Uma tarefa é a menor unidade de trabalho que o Spark envia a um executor. O ponto de entrada principal para as funcionalidades do Spark é o SparkContext, que o programa driver usa para acessar o Spark. Um SparkContext representa uma conexão com um cluster de computação.

4. Aplicações com Apache Spark

A versatilidade e desempenho do Spark têm levado a sua adoção em uma variedade de setores por ser uma ferramenta de processamento de dados que se destaca pela sua capacidade de processar grandes volumes de dados em alta velocidade. Aqui estão algumas das principais aplicações de Apache Spark:

Saúde: Uma aplicação no setor de saúde é a utilização do Apache Spark para uma análise detalhada dos registros de pacientes juntamente com dados médicos anteriores. Isso permite identificar quais pacientes são propensos a enfrentar complicações de saúde no futuro, ajudando a evitar readmissões hospitalares. A redução de readmissões hospitalares diminui os custos tanto para os hospitais quanto para os pacientes, tornando viável a implementação de serviços domiciliares para os pacientes identificados. Além disso, Spark é usado na sequenciação genômica, reduzindo o tempo necessário para processar dados de genomas, que anteriormente poderia levar várias semanas para organizar todos os compostos químicos com genes.

Finanças: No setor financeiro, Apache Spark oferece insights que ajudam a tomar decisões corretas sobre diversas questões, como segmentação de clientes, avaliação de risco de crédito e publicidade direcionada. Instituições financeiras usam big data para determinar o momento e local exatos em que fraudes ocorreram, permitindo que sejam interrompidas. Existem vários modelos para detectar transações falsas, muitos dos quais são implantados em ambientes de batch. Com a ajuda do Apache Spark no Hadoop, as instituições financeiras podem detectar transações fraudulentas em tempo real, com base em padrões de fraudes anteriores.

Comércio Eletrônico: Na indústria de comércio eletrônico, empresas como Alibaba e eBay utilizam o Spark para analisar transações em tempo real, que são passadas para algoritmos de clustering de streaming, como o algoritmo K-means ou o método de mínimos quadrados alternados. Além disso, melhora as recomendações aos clientes com base nas tendências mais recentes.

Entretenimento: Na indústria de jogos, Apache Spark ajuda a reconhecer padrões em eventos de jogos em tempo real e a responder a eles para gerar oportunidades de negócios, como publicidade seletiva, retenção de jogadores ou alteração automática dos níveis de dificuldade dos jogos. Além disso, quando combinado com o MongoDB, Spark é usado em sites de compartilhamento de vídeos, como Pinterest, Netflix e Yahoo. Esses sites mostram anúncios relacionados aos usuários com base nos vídeos visualizados, compartilhados e navegados pelos usuários.

4.1. Spark para Machine Learning

Spark MLlib

O Spark MLlib é a biblioteca original de aprendizado de máquina do Spark. Ela inclui uma ampla gama de algoritmos para filtragem colaborativa, clusters, classificação e regressão. Alguns dos principais recursos e benefícios do MLlib incluem:

  • Escalabilidade: Projetado para operar em grandes volumes de dados, o MLlib pode ser executado em clusters distribuídos, aproveitando o poder de processamento paralelo do Spark.
  • Facilidade de uso: Oferece APIs simples e intuitivas, facilitando a construção e implementação de algoritmos de aprendizado de máquina.
  • Algoritmos Diversificados: Inclui algoritmos para classificação (como árvores de decisão e SVMs), regressão (como regressão linear e logística), clustering (como K-means) e filtragem colaborativa (como ALS).

Spark ML

O Spark ML é um pacote mais recente que fornece uma API de nível superior criada com base em DataFrames para a construção de pipelines de ML. Este pacote foi desenvolvido para melhorar a integração com outras operações de dados do Spark e oferecer uma experiência mais unificada para os usuários. As principais características do Spark ML incluem:

  • Pipelines de ML: Permite a construção de pipelines de aprendizado de máquina que podem incluir estágios de transformação de dados, treinamento de modelos e avaliação de modelos.
  • DataFrames: Utiliza DataFrames para representar dados, proporcionando uma integração mais eficiente com as operações de SQL e otimizações automáticas.
  • Facilidade de Uso e Integração: Embora ainda esteja evoluindo para incluir todos os recursos do MLlib, o Spark ML oferece uma API mais moderna e fácil de usar para a construção de modelos de aprendizado de máquina.

Execução do Apache Spark

O Apache Spark pode ser executado em diversos ambientes, incluindo sua própria estrutura de cluster, clusters Hadoop, na nuvem ou em modo standalone. Ele é projetado para ser rápido, escalável e versátil, suportando operações de processamento de dados em tempo real e aprendizado de máquina.

Integração com Bibliotecas Populares

Para treinar modelos de machine learning com o Apache Spark, é possível usar bibliotecas populares como Scikit-Learn, XGBoost e MMLSpark:

  • Scikit-Learn: Embora seja tradicionalmente uma biblioteca para execução local, ela pode ser integrada com Spark para distribuir tarefas de treinamento.
  • XGBoost: Uma biblioteca de boosting que pode ser executada de forma distribuída em clusters Spark, aproveitando sua capacidade de processamento paralelo.
  • MMLSpark: Uma biblioteca desenvolvida pela Microsoft, projetada para aumentar a produtividade dos cientistas de dados no Spark, aumentar a taxa de experimentação e aproveitar técnicas avançadas de machine learning.

4.2. Spark para Big Data

Velocidade

Spark é extremamente rápido devido ao seu mecanismo de processamento na memória, que evita leituras e gravações constantes em disco. Comparado com o Hadoop MapReduce, Spark pode ser até 100 vezes mais rápido em certas cargas de trabalho.

Escalabilidade

Spark pode ser escalado para processar petabytes de dados, utilizando clusters de milhares de nós. Ele é projetado para ser executado em diversos ambientes, incluindo clusters Hadoop, Amazon EC2, Kubernetes, e em modo standalone.

Facilidade de Uso

Spark oferece APIs de alto nível em Java, Scala, Python e R, tornando-o acessível para desenvolvedores e cientistas de dados com diferentes backgrounds. Suas APIs simples e intuitivas facilitam a construção de aplicações complexas de Big Data.

Versatilidade

Spark suporta diversas operações de processamento de dados, incluindo SQL, streaming, aprendizado de máquina e processamento de grafos, todas integradas em um único framework unificado.

Análise de Dados de Log

Empresas utilizam Spark para processar e analisar grandes volumes de logs de servidor, identificando padrões de uso e detectando anomalias em tempo real.

Processamento de Streams de Dados

Spark Streaming é usado para processar fluxos de dados em tempo real, como dados de sensores IoT, transações financeiras e logs de redes sociais, permitindo respostas rápidas a eventos.

Recomendações Personalizadas

Com MLlib, empresas de e-commerce e streaming de mídia implementam sistemas de recomendação que analisam grandes volumes de dados de usuário para fornecer recomendações personalizadas.

Análise de Sentimento

Spark é usado para processar dados de texto em grande escala, como posts em redes sociais e reviews de produtos, para análise de sentimentos e tendências de mercado.

Processamento de Dados Genômicos

Spark permite o processamento e análise rápida de grandes volumes de dados genômicos, acelerando pesquisas em bioinformática e medicina personalizada.

4.3. Spark para Processamento de Grafos

O Apache Spark é amplamente utilizado em aplicações de Big Data, incluindo processamento de grafos. O Spark GraphX é uma API do Apache Spark que fornece funções para a computação paralela de grafos, permitindo a análise de grafos complexos de forma eficiente.

Spark GraphX

O GraphX estende o Spark RDD, introduzindo uma nova abstração do grafo: um multigrafo direcionado com propriedades anexadas a cada vértice e aresta. Ele fornece operadores e algoritmos integrados para transformar grafos, permitindo a construção de grafos a partir de coleções de vértices e arestas em RDDs ou no disco. Além disso, o GraphX inclui vários algoritmos e construtores de grafos para uso em análises de grafos.

O processamento de grafos com o Spark é especialmente útil em aplicações que envolvem relações complexas entre entidades, como redes sociais, redes de computadores e problemas de logística. O Spark GraphX facilita a análise de grafos com operadores e algoritmos integrados, permitindo a armazenagem e remoção do cache dos grafos para evitar recálculo quando necessário.

GraphFrames

Outra biblioteca importante do Spark para processamento de grafos é o GraphFrames. Esta ferramenta integra recursos como pattern matching e algoritmos de grafo com o Spark SQL, representando vértices e arestas como DataFrames em vez de objetos RDD. Isso simplifica o pipeline de análise dos grafos e otimiza as consultas nos grafos e nos dados relacionados.

Casos de Uso Comuns no Processamento de Grafos

  • Análise de Redes Sociais: O Spark é amplamente utilizado para a análise de redes sociais, como a identificação de usuários influentes, a detecção de padrões de comportamento e a análise de relacionamentos entre usuários.
  • Roteamento em Redes de Computadores: O Spark é utilizado para desenvolver algoritmos de roteamento em redes de computadores, permitindo a otimização do tráfego de dados e a melhoria da eficiência da rede.
  • Logística e Roteirização de Veículos: O Spark é aplicado em problemas de logística, como a roteirização de veículos e a definição do melhor caminho para entrega de produtos.
  • Análise de Dados de Movimento: O Spark é utilizado para a análise de dados de movimento, como a detecção de padrões de comportamento em grandes conjuntos de dados de locomoção.
  • Análise de Conexões entre Entidades: O Spark é aplicado para a verificação de conexões entre entidades, como a detecção de relacionamentos entre usuários em redes sociais.
  • Algoritmos de PageRank: O Spark é utilizado para a implementação do algoritmo de PageRank, desenvolvido pelo Google, que é usado para avaliar a relevância de páginas na web.

Esses casos de uso demonstram a ampla aplicação do Apache Spark no processamento de grafos, permitindo a análise de grandes conjuntos de dados de forma eficiente e escalável. Com ferramentas como GraphX e GraphFrames, o Spark se torna uma plataforma essencial para explorar e analisar as complexas relações presentes em dados de grafos, impulsionando insights valiosos em diversas áreas.

4.4. Spark para Processamento de Fluxo (Stream Processing)

O módulo de processamento de fluxo, Spark Streaming, é essencial para lidar com dados em tempo real. Projetado para ser rápido, escalável e fácil de usar, Spark Streaming permite processar e analisar dados contínuos de várias fontes em tempo real.

Principais Características do Spark Streaming

  • Micro-batching: Spark Streaming divide os dados em pequenos lotes (micro-batches) e os processa em intervalos regulares, combinando a simplicidade do processamento em lote com a necessidade de respostas em tempo real.
  • Integração com o Ecossistema Spark: Totalmente integrado com o Spark Core, Spark SQL, MLlib e GraphX, permitindo o uso de todas as capacidades do Spark para análise de dados de fluxo em tempo real.
  • Tolerância a Falhas: Utiliza a abstração de Resilient Distributed Datasets (RDDs) para garantir a recuperação de dados em caso de falhas, mantendo a integridade e a consistência dos dados processados.
  • Suporte a Várias Fontes de Dados: Pode receber dados de várias fontes, incluindo Kafka, Flume, HDFS, S3, sockets TCP, entre outras, proporcionando flexibilidade para diferentes cenários de fluxo de dados.
  • Processamento de Estado: Oferece suporte para operações de janela (window operations) e estado completo (full-state) para manter e manipular dados de estado em fluxos contínuos.

Componentes Principais

  • DStreams (Discretized Streams): A unidade básica de Spark Streaming, que representa um fluxo contínuo de dados divididos em pequenos lotes. Os DStreams podem ser criados a partir de fontes de dados de fluxo ou transformados a partir de outros DStreams.
  • Transformações e Ações: Permite aplicar uma variedade de transformações (como map, filter, reduceByKey) e ações (como count, save) aos DStreams, semelhante às operações em RDDs no Spark Core.
  • Operações de Janela: Permite a aplicação de transformações em janelas deslizantes de dados, facilitando a agregação e análise de dados em períodos específicos de tempo.
  • Estado Completo: Mantém o estado de dados ao longo do tempo, permitindo operações como contagem de palavras, agregações por chave, e outras operações que exigem a manutenção de informações de estado.

Integração com Kafka

Uma das integrações mais populares do Spark Streaming é com o Apache Kafka, uma plataforma distribuída de transmissão de eventos. Spark Streaming e Kafka juntos proporcionam uma solução robusta para pipelines de dados em tempo real.

  • Kafka Direct API: Permite a leitura direta de tópicos do Kafka e a conversão de dados em DStreams para processamento em tempo real.

Casos de Uso Comuns

  • Monitoramento de Redes Sociais: Empresas utilizam Spark Streaming para analisar em tempo real menções e interações em redes sociais, ajudando na detecção de tendências e no gerenciamento de marca.
  • Detecção de Fraudes: Instituições financeiras empregam Spark Streaming para monitorar transações em tempo real e detectar atividades fraudulentas com base em padrões de comportamento anômalos.
  • Análise de Logs e Monitoramento de Servidores: Empresas de TI usam Spark Streaming para processar e analisar logs de servidor em tempo real, identificando e respondendo rapidamente a problemas de desempenho e segurança.
  • Internet das Coisas (IoT): Spark Streaming é utilizado para processar dados de sensores IoT, permitindo monitoramento em tempo real de máquinas, veículos e outros dispositivos conectados.
  • Recomendações em Tempo Real: Plataformas de e-commerce e streaming utilizam Spark Streaming para analisar o comportamento dos usuários em tempo real e fornecer recomendações personalizadas instantaneamente.

5. Conclusões

O Apache Spark, de fato, intruduziu muitos avanços computacionais na área de dados. Suas abstrações e as escolhas arquiterurais feitas, o tornaram o formato padrão para se lidar com dados, mostrando ser, de fato, um avanço.

Sua adoção vai além da indústria e chega até as universidades (uma vez que nasceu em uma) e se mostra útil para a resolução de questões públicas, pesquisas, e o que mais utilizar dados para alguma tomada de decisão ou avanço tecnológico/científico.

Sua facilidade e a possibilidade de integrar com diversas linguagens de programação também torna essa ferramenta muito útil. Ora, analistas de dados se especializam (quase sempre) em algumas linguagens já glorificadas, tais como Python, R e SQL. De uma forma simples, é possível que cada uma dessas linguagens utilize a API do Spark.

Tudo isso faz do Spark uma ferramenta necessária nos dias atuais na indústria ou universidades.

6. Bibliografia

- Apache Spark: A Big Data Processing Engine
11/2019
Conference: 2019 2nd IEEE Middle East and North Africa COMMunications Conference (MENACOMM)

- Spark Architecture: A Deep Dive
06/2023
Amit Joshi

- Apache Spark Architecture – Detailed Explanation
01/2024

- Apache Spark: Architecture, Best Practices, and Alternatives
Omer Mesika

- Understand The Internal Working of Apache Spark
Dhanya Thailappan
08/2021

- Cluster Mode Overview (Spark Docs)
Spark Documentation

- Big data analytics on Apache Spark
10/2016
Salloum, S., Dautov, R., Chen, X. et al. Big data analytics on Apache Spark. Int J Data Sci Anal 1, 145–164 (2016). https://doi.org/10.1007/s41060-016-0027-9

- SPARK: Criando Cluster com Docker
09/2023
Douglas S. Souza

- DAGs Apache Spark

- Apache Spark (IBM)

- O que é Apache Hadoop? (Google)

- O que é Hadoop (AWS)