Você está na página 1de 16

FRAMEWORK

DE BIG DATA

Fabiano Berlinck Neumann


Overview de frameworks
de stream de big data
Objetivos de aprendizagem
Ao final deste texto, você deve apresentar os seguintes aprendizados:

„ Descrever o Spark Streaming.


„ Comparar tecnologias utilizadas para stream de big data.
„ Esquematizar a ingestão de um stream de dados.

Introdução
Existem cenários com características específicas de streaming de big
data, como no caso de uma instituição financeira que rastreia em tempo
real as mudanças de mercado para ajustar as operações das carteiras
de investimento com base em limites máximos e mínimos, ou no caso
de soluções de Internet das Coisas que crescem a cada dia e sensores
de monitoramento que fazem o envio constante das suas leituras para
uma ou mais estações. Para lidar com esses cenários, é necessário utilizar
tecnologias que possam tratar séries temporais e realizar o processamento
à medida que os dados chegam, ao invés de esperar o final da mensagem
para realizar o processamento, pois, nesses casos, as mensagens não
contêm um sinal de fim de arquivo por serem um fluxo constante de
dados, que em teoria não tem fim.
Neste capítulo, você vai conhecer uma visão geral de frameworks
de stream de big data, saber mais sobre o Spark Streaming, por meio da
descrição de suas características e da comparação com outras tecnologias
utilizadas para stream de big data, bem como pela ingestão de um stream
de dados simples.
2 Overview de frameworks de stream de big data

1 Conhecendo o Spark Streaming


De acordo com a documentação do Apache Spark Streaming, o framework
torna simples o desenvolvimento de aplicações em stream de dados de alta
taxa de transferência, de forma que as aplicações sejam escaláveis e tolerantes
a falhas sem que haja a necessidade de escrita de código extra para esses fins.
A simplicidade se dá por conta dos operadores de alto nível contidos em sua
API integrada para o processamento dos fluxos de dados, o que permite que
o desenvolvedor crie serviços de stream de dados da mesma forma que cria
serviços para lotes de dados. No entanto, a tolerância a falhas se dá pela sua
recuperação de trabalho perdido e das janelas deslizantes.
De acordo com Dayananda (2019), Spark Streaming tem como principais
recursos a escalabilidade, pois pode ser facilmente escalonado para centenas
de nós; a velocidade, por atingir baixa latência ou processar em tempo real
em certos casos; a tolerância a falhas; a sua integração entre processamento
de fluxos de dados e de lotes; e a sua disponibilidade para a realização de
análise de negócios, pois pode ser utilizado para rastrear comportamentos que
podem ser utilizados estrategicamente para a tomada de decisão das empresas.
Como o Spark Streaming roda em cima da API principal do Spark, ele
permite a combinação de operações em fluxos ativos de dados com dados
em lotes e buscas interativas, bem como o reúso de código de streaming
para processamento em lote, unindo os fluxos com dados históricos, o que
possibilita a criação de aplicações interativas, além das aplicações de análise.
Os dados das aplicações que tratam esses fluxos podem ser ingeridos por
diversas fontes distintas, como plataformas de código aberto, e proprietário,
como o Apache Kafka, o Apache Flume e o Amazon Kinesis, ou de sockets
TCP. Esses dados podem ser processados com algoritmos complexos por meio
das funções de alto nível, como map, reduce, join e window.
Os dados resultantes desse processamento podem ser armazenados em
bancos de dados e sistemas de arquivos, como o HDFS, ou o Hadoop Distributed
File System, bem como podem ser enviados para dashboards, conhecidos como
painéis de controle. Também é possível executar algoritmos de aprendizagem
de máquina e de processamento gráfico nos fluxos de dados.
Internamente, o Spark Streaming recebe um fluxo de dados de entrada em
tempo real e divide esses dados em lotes em intervalos de tempo predefinido.
Esses lotes são chamados de microlotes e são processados pelo motor do Spark,
o que resulta em um fluxo final também composto por um conjunto de lotes,
conforme apresentado na Figura 1.
Overview de frameworks de stream de big data 3

Figura 1. Funcionamento interno do Apache Spark Streaming.


Fonte: Adaptada de Apache Spark ([201–?]).

De acordo com Penchikala (2016), após a divisão dos dados em microlotes,


eles são tratados como RDDs, acrônimo para Resilient Distributed Datasets,
que são coleções de elementos. O autor também afirma que a decisão do
intervalo de tempo a ser utilizado é de extrema importância para o projeto e
deve ser baseado no caso de uso que se quer analisar, bem como nos requisitos
de processamento de dados.
Caso o tempo seja muito baixo, os microlotes não irão conter dados sufi-
cientes para que os resultados da análise sejam significativos, e caso seja muito
alto, podem faltar recursos para o processamento dos microlotes.

Fluxos discretizados (DStreams)


O Spark Streaming fornece uma abstração de alto nível que representa um
fluxo contínuo de dados chamado DStream, acrônimo para fluxo discretizado,
do inglês discretized stream. Internamente, um DStream é representado por
uma série contínua ou sequência de RDDs, que é a abstração do Spark para um
conjunto de dados distribuído e imutável, e contém os dados de um intervalo
de tempo, conforme pode ser observado na Figura 2.

Figura 2. RDDs no DStream com dados de determinado intervalo de tempo.


Fonte: Adaptada de Apache Spark ([201–?]).

Além disso, cada operação que acontece em um DStream é convertida em


operações nos RDDs que seguem, como no caso de um fluxo de entrada que
chega na forma de linhas e é convertido para palavras, no qual a operação
4 Overview de frameworks de stream de big data

flatMap é executada em cada um dos RDDs nas linhas do stream discreti-


zado para gerar os RDDs das palavras de saída DStream. A Figura 3 apresenta
um exemplo que mostra o fluxo de uma aplicação usando Spark que conta o
número de palavras dos textos recebidos de um servidor de dados que escuta
de um socket TCP.

Figura 3. Replicação da operação flatMap nos RDDs subjacentes do DStream.


Fonte: Adaptada de Apache Spark ([201–?]).

Neste caso, as operações do DStream ocultam grande parte desses


detalhes de replicação das operações para outros RDDs e disponibilizam
uma API de alto nível para os desenvolvedores, tendo em vista que as
transformações subjacentes nos RDDs são executadas pelo motor do Apache
Spark. Esse fluxo contínuo de dados representado pelo Spark Streaming
como DStream pode ser o fluxo de dados de entrada que é recebido da fonte
ou o fluxo de dados processados de saída que é gerado pela transformação
do fluxo de entrada.
Quando se trata de um fluxo de entrada, o DStream diz respeito aos
dados de entrada recebidos por meio das fontes de stream, que podem ser
criadas a partir de operações de alto nível em outros DStreams, além das
outras fontes citadas anteriormente, como das plataformas como Kaf ka,
Flume e Kineses. Além disso, todo DStream de entrada é associado a um
objeto do tipo Receiver, que recebe os dados da fonte e os armazena na
memória do Spark para o processamento, conforme pode ser observado
na Figura 4.
Overview de frameworks de stream de big data 5

Figura 4. DStream de entrada com o objeto do tipo Receiver para receber os dados.
Fonte: Adaptada de Dayananda (2019).

O DStream suporta diversas das transformações normalmente permitidas nos


RDDs do Spark, como map, flatMap, filter, reduce, join, transform
e updateStateByKey, e, assim como no caso dos RDDs, as transformações
permitem que os dados do DStream de entrada sejam modificados.
Em se tratando do DStream de saída, que representa o fluxo de dados
processados, são as operações de saída que permitem que os dados sejam
enviados para sistemas externos, como bancos de dados e sistemas de ar-
quivos, e, assim como no caso dos RDDs, são essas operações que acionam
a execução de todas as transformações no DStream que não são executadas
imediatamente quando chamadas.

2 Spark Streaming e outros frameworks


Além do Spark Streaming, existem outros frameworks que permitem tratar
fluxos contínuos de dados, como o Structured Streaming do Spark, o Kinesis
Streams da Amazon, o Flink, o Storm, o Kafka e o Samza, todos da Apache.
Neste capítulo, o framework Apache Spark Streaming será comparado com
o Spark Structured Streaming, o Apache Flink e o Apache Storm.

Spark Streaming e Spark Structured Streaming


O Spark é uma ferramenta muito popular por conta do seu processamento rápido
e distribuído, sem sobrecarga de entrada e saída, com tolerância a falhas, entre
outras qualidades. Voltado para soluções de big data, ele permite o processamento
de vastas quantidades de dados, bem como trabalhar com processamento de
6 Overview de frameworks de stream de big data

fluxos contínuos de dados em tempo real. Para lidar com esses fluxos de dados,
o Spark disponibiliza duas ferramentas, uma é o Spark Streaming, apresentado
anteriormente neste capítulo, e a outra é o Structured Streaming.
De acordo com Saxena (2019), o Spark Structured Streaming surgiu com
a versão 2 do Spark como mais uma forma de lidar com fluxos contínuos de
dados e foi construído na biblioteca Spark SQL. Baseado nas APIs Dataframe
e Dataset, ele torna fácil a execução de consultas SQL com a API Dataframe
e operações com a API Dataset nos fluxos de dados.
Uma das diferenças entre eles é a forma como tratam os fluxos de dados
em tempo real. Enquanto o Spark Streaming utiliza o conceito de divisão em
microlotes e cada lote pertence a um lote do DStream, representado por dife-
rentes RDDs, o Structured Streaming processa cada linha do fluxo de dados
e o resultado é a atualização de uma tabela de resultados. Além disso, com
o Structured Streaming é possível que a tabela resultante seja composta por
uma atualização dos dados, apenas novos resultados ou todos os resultados,
dependendo do modo das operações utilizadas.
A segunda diferença tem relação com as diferentes APIs de cada um dos
modelos. Enquanto o Spark Streaming utiliza a API DStream, que internamente
funciona com RDDS, o Structured Streaming utiliza APIs Dataframe e Dataset.
Dessa forma, conforme apresentado por diversos autores, os Dataframes são
mais otimizados quando se trata de processamento, além de oferecerem mais
opções de agregação e outras operações com funções suportadas no Spark.
Outra diferença diz respeito à forma de processamento de dados com base
no horário exato do acontecimento do evento. No Spark Streaming, o controle
do tempo só tem relação com o momento em que o dado é ingerido pelo Spark,
quando os dados são colocados em um lote atual, mesmo que o evento tenha
acontecido mais cedo e pertença ao lote anterior, o que pode ser considerado
como perda de dados e gerar informações menos precisas.
Todavia, no caso do Structured Streaming, um dos principais recursos
introduzidos é o tratamento de dados atrasados com base no horário do acon-
tecimento do evento, de forma que o registro de data e hora do acontecimento
do evento no mundo real é inserido na tabela de resultados, fornecendo uma
maneira diferente de processar os dados, se comparado ao Spark Streaming.
Em se tratando de tolerância a falhas, em ambos os frameworks é utilizado
o conceito de ponto de controle para guardar o progresso de um trabalho,
pois para que uma aplicação seja tolerante a falhas ela precisa ter capacidade
de reiniciar a partir do ponto de falha, de forma a evitar perda de dados, no
caso de retomar em um ponto posterior, ou a duplicação de dados, no caso de
retomar em um ponto anterior.
Overview de frameworks de stream de big data 7

A diferença entre eles é que o Structured Streaming utiliza duas condições


para se recuperar de qualquer erro, além do ponto de controle, tendo em vista
que essa abordagem ainda permite perda de dados. A primeira é que a fonte de
dados deve ser repetível e a segunda é que as áreas de destino das operações
nos fluxos de dados devem suportar operações idempotentes para que os dados
possam ser reprocessados em caso de falhas.

Spark Streaming, Apache Flink e Apache Storm


Assim como o Spark Streaming, o Apache Flink e o Apache Storm são pro-
jetados para tratar os dados em memória e processá-los em tempo real, sem,
necessariamente, persistirem os dados em outros tipos de armazenamento,
apesar de ser possível gravá-los em bancos de dados e sistemas de arquivos,
pois o propósito dos frameworks de streaming é processar os dados em tempo
real à medida que eles chegam. A grande diferença entre eles é que o Flink
e o Storm são baseados em uma arquitetura diferente do Spark Streaming,
pois foram criados do zero com o propósito de trabalhar com um motor nativo
para streaming, enquanto o Spark contém um motor baseado no conceito de
tratamento de stream de dados com microlotes.
Os modelos nativos de tratamento de streaming foram projetados especi-
ficamente para resolver os desafios de aplicações que exigem processamento
em tempo real baseado em recebimento de eventos, no qual o fluxo de dados é
obtido das fontes ao longo do tempo e é processado individualmente à medida
que é recebido, o que ajuda a manter um menor tempo de espera antes que o
dado entre no sistema. Como resultado, esse tipo de arquitetura tem uma menor
latência se comparada ao modelo orientado a microlotes do Spark Streaming.
Em relação à tolerância a falhas, como visto anteriormente, o Spark Stre-
aming utiliza o conceito de gerenciamento de estado por ponto de verificação
para replicar continuamente o estado para outros nós, para que, quando a
falha aconteça, o dado possa ser extraído do outro nó e o processamento seja
reiniciado, o que é um processo mais custoso em motores de stream nativos
no sentido de recursos, pois é aplicado a cada nível de registro.
De acordo com Gorasiya (2019), apesar de esse controle ser mais custoso, o
Flink também utiliza pontos de verificação para a sua recuperação de falhas.
No entanto, o Storm não fornece gerenciamento de estados, o que força o
reinício do processo inteiro em diferentes nós, gerando, assim, a garantia de
processamento “ao menos uma vez”, diferentemente dos dois anteriores, que
têm a garantia de processamento de “exatamente uma vez”.
8 Overview de frameworks de stream de big data

A diferença entre a gestão de estados do Spark Streaming e do Flink é que


no Spark ela está associada com os RDDs e envolve a atualização de cada lote,
mesmo que o estado não seja alterado, tornando-o extremamente ineficiente se
comparado ao Flink. No caso do Flink, tem suporte eficiente para integrar o
gerenciamento de estado com a ajuda de um sistema de arquivos distribuídos,
de forma a manter o controle do estado por meio de um retrato fiel da situação
em determinado momento.
Para Gorasiya (2019), outra diferença é em relação à escalabilidade, pois, no
Spark, as soluções escalam automaticamente, enquanto no Flink e no Storm,
esse processo é manual. Além disso, o Spark tem uma ampla comunidade que
trabalha, dá suporte e discute sobre a tecnologia, enquanto no Flink, a comu-
nidade ainda está em crescimento e no Storm, a comunidade de colaboradores
é pequena se comparada aos dois anteriores.
Segundo Prakash (2018), o Storm é o projeto de código aberto mais antigo
para trabalhar com streaming e um dos mais maduros e confiáveis. Excelente
para trabalhar com casos de uso que não sejam complexos, ele tem latência
muito baixa e alta taxa de transferência. Entretanto, tem desvantagens, como
o fato de não controlar estados, controle de garantia de processamento de “ao
menos uma vez” e não tem funcionalidades avançadas, como o processamento
de evento baseado no horário do acontecimento, agregação, separação em
janelas, sessões, entre outros.
O autor afirma que as principais vantagens do Spark Streaming são que
ele suporta arquitetura Lambda, que é disponibilizada gratuitamente com o
Spark, tem alta taxa de transferência, tolerância a falhas por padrão por conta
da sua natureza de microlotes, além de ter simplicidade no uso de APIs de alto
nível, uma comunidade grande e melhorias agressivas no framework. Suas
principais desvantagens dizem respeito a não ser nativamente criado para
streaming e não é adequado para alguns casos de requisitos de baixa latência
se comparado a outros frameworks.
Em se tratando do Flink, é o líder em inovação quando se trata de framework
de streaming de código aberto. Foi o primeiro projeto nativo para streaming
com funcionalidades avançadas, como processamento de evento com horário
do acontecimento, separação em janelas, entre outros. Ele tem baixa latência
com alta taxa de entrega, que pode ser configurada de acordo com os requisitos
da aplicação. Entretanto, suas desvantagens dizem respeito à sua popularidade
se dar apenas em aplicações de streaming e à sua falta de adoção inicial, o
que o colocou mais tarde na competição contra outros frameworks, tendo uma
comunidade menor do que o Spark.
Overview de frameworks de stream de big data 9

3 Ingestão de dados com o Spark Streaming em


Java
Para entender o funcionamento da ingestão de dados em uma aplicação com
o Spark Streaming, vamos estudar o uso em Java de uma aplicação simples
para contagem de palavras nos dados de texto recebidos de um servidor por
meio da escuta de um socket TCP, que, neste caso, vai ser exemplificado pelo
endereço localhost e pela porta 9999.

Etapas para criar um programa com Spark Streaming


Uma vez instalado o Spark Streaming, é necessário seguir uma série de passos
para criar uma aplicação que utilize stream de dados, sendo o primeiro deles
a definição das importações (imports), que serão apresentadas a seguir no
código de exemplo. Com as devidas importações, inicialmente é necessário
criar o objeto do tipo SparkConf especificando o nome da aplicação. No
trecho de código a seguir, utiliza-se o ambiente local para isso:
SparkConf config uracao = new S p a r k C o n f ( ).
setAppName(“ContadorPalavrasStreaming”);

Em seguida, é criado o objeto do tipo JavaStreamingContext para


receber a configuração do objeto SparkConf como parâmetro e o intervalo
de tempo de cada lote. Esse objeto é o ponto de entrada para todas as funcio-
nalidades de streaming e, no caso do exemplo apresentado, foi configurado
em 1 segundo:
JavaStreamingContext ssc = new JavaStreamingContext(configu-
racao, Durations.seconds(1));

A partir desse objeto de contexto, é possível criar um JavaReceive-


rInputDStream no ip:porta de destino. O código a seguir conta as palavras
no stream de entrada de texto delimitado por \n (por exemplo, gerado por
nc). Observe que não há duplicação no nível de armazenamento apenas para
execução local. Contudo, para que sejam toleradas falhas, a replicação se faz
necessária.
JavaReceiverInputDStream<String> linhas = ssc.socketTextStream(
args[0], Integer.parseInt(args[1]), StorageLevels.
MEMORY _ AND _ DISK _ SER);
JavaDStream<String> palavras = linhas.flatMap(x -> Arrays.
asList(SPACE.split(x)).iterator());
10 Overview de frameworks de stream de big data

JavaPairDStream<String, Integer> palavrasContadas = pala-


vras.mapToPair(s -> new Tuple2<>(s, 1))
.reduceByKey((i1, i2) -> i1 + i2);
A variável linhas representa o fluxo de dados que será recebido do
servidor, e cada entrada vinda do servidor representa uma linha do texto
como um todo. Para que essa linha seja processada e para que seja realizada
a sua separação em palavras pelo espaço em branco, é necessário utilizar
a operação flatMap, que recebe uma lista como parâmetro. Ela deve ser
separada na variável x por meio dos métodos split e iterator, para que,
então, cada uma das palavras possa ser atribuída à variável palavras do
tipo JavaDStream.
Para a realização da contagem de palavras, é utilizada a operação mapTo-
Pair no JavaDStream palavras e, no seu resultado, o qual também é uma
variável do tipo JavaDStream de nome palavrasContadas, é realizada a
operação reduceByKey. Segundo a documentação oficial do Spark — que
você pode encontrar ao buscar por “Spark Java API reducebykey” na internet
—, a operação reduceByKey mescla os valores de cada uma das chaves e,
para isso, utiliza uma função de redução associativa e comutativa. Essa ope-
ração faz uma mesclagem local em cada mapper e, feito isso, os resultados
são enviados a um reducer, como um combiner no MapReduce. A saída
será particionada de acordo com o calor estabelecido em numPartitions
ou, se esse parâmetro não estiver especificado, com o nível de paralelismo
padrão. O algoritmo de particionamento utilizado é o hash.
Em seguida, o resultado é armazenado no JavaPairDStream palavras-
Contadas, que recebe a operação print para que seus valores sejam escritos
no terminal à medida que são processados. O trecho da impressão pode ser
visto a seguir:

palavrasContadas.print();

Com o código escrito até agora, foi realizada a configuração do que deverá
ser executado pelo Spark Streaming sem que aconteça algum tipo de processa-
mento até que a operação de chamada de início aconteça explicitamente, por
meio da função start do objeto de contexto do Spark Streaming. Além disso,
deve-se esperar a execução terminar pela operação awaitTermination,
como pode ser visto no trecho de código que segue:

ssc.start();
ssc.awaitTermination();
Overview de frameworks de stream de big data 11

Neste caso, a classe que contém o código foi chamada de ContadorPa-


lavrasStreaming. O código completo pode ser visto na Figura 5.

Figura 5. Código de exemplo completo.

Exemplo

Veja, a seguir, um passo a passo de execução do código aplicado a uma má-


quina virtual da Cloudera.

1. Faça o download do VirtualBox na sua página oficial.


2. Faça o download da Cloudera CDH pela página oficial da empresa.
3. Instale o VirtualBox e inicie a VM da Cloudera.
4. Já logado na VM, faça o download do código fonte disponível na
seção Conteúdo do Livro da Unidade de aprendizagem.
5. Abra o terminal do Linux, vá até a pasta do download e descompacte:
$ unzip Codigo.zip /contador
12 Overview de frameworks de stream de big data

6. Para que seja possível rodar um servidor de dados de texto localmente,


é preciso utilizar o serviço Netcat, que está presente na maioria dos
sistemas operacionais baseados em Unix, como Linux e MacOS,
por meio de comando no terminal. O comando a seguir será a fonte
do stream:
$ nc -lk 9999
7. Em um segundo terminal, vá até o diretório de instalação do Spark
(pasta bin). Na VM da Cloudera, usualmente é /usr/lib/spark.
$ cd /usr/lib/spark
8. Execute o programa passando como parâmetro o local onde está seu
código. No exemplo, o arquivo .java está em ~/Downloads/
Codigo:
$ ./run-example ~/Downloads/Codigo/ContadorPalavrasStreaming.
java localhost 9999
9. No outro terminal, onde você usou o comando nc -lk 9999, digite
um texto e pressione a tecla Enter (Figura 6).

Figura 6. Exemplo de inputde dados com texto digitado.

10. Dessa forma, serão apresentadas no terminal as palavras e os seus


respetivos números de contagem (Figura 7).
Overview de frameworks de stream de big data 13

Figura 7. Saída para o exemplo de entrada apresentado na Figura 6..

Com isso, é possível conhecer uma visão geral sobre o Apache Spark Streaming,
observar suas características e as diferenças entre ele e outros frameworks,
como o Apache Structured Streaming, o Apache Flink e o Apache Storm, bem
como entender como seria a programação em Java de uma aplicação simples
de ingestão de dados em streaming.
14 Overview de frameworks de stream de big data

APACHE SPARK. Spark streaming programming guide. Apache Spark, [s. l.], [201–?].
Disponível em: https://spark.apache.org/docs/latest/streaming-programming-guide.
html. Acesso em: 30 mar. 2020.
DAYANANDA, S. Spark streaming tutorial: sentiment analysis using apache spark. Edu-
reka!, [s. l.], 22 May 2019. Disponível em: https://www.edureka.co/blog/spark-streaming/.
Acesso em: 30 mar. 2020.
GORASIYA, D. Comparison of open-source data stream processing engines: Spark
streaming, Flink and Storm. Technical Report, [s. l.], 2019. Disponível em: https://www.
researchgate.net/publication/336141201_Comparison_of_Open-Source_Data_Stream_
Processing_Engines_Spark_Streaming_Flink_and_Storm. Acesso em: 30 mar. 2020.
PENCHIKALA, S. Big Data com Apache Spark Part 3: Spark streaming. Info Q, [s. l.], 5 dez.
2016. Disponível em: https://www.infoq.com/br/articles/apache-spark-streaming/.
Acesso em: 30 mar. 2020.
PRAKASH, C. Spark streaming vs Flink vs Storm vs Kafka Streams vs Samza: Choose
your stream processing framework. Medium, [s. l.], 1 May 2018. Disponível em: https://
medium.com/@chandanbaranwal/spark-streaming-vs-flink-vs-storm-vs-kafka-streams-
-vs-samza-choose-your-stream-processing-91ea3f04675b. Acesso em: 30 mar. 2020.
SAXENA, A. Spark streaming vs. structured streaming. DZone, [s. l.], 29 mar. 2019. Dis-
ponível em: https://dzone.com/articles/spark-streaming-vs-structured-streaming.
Acesso em: 30 mar. 2020.

Os links para sites da web fornecidos neste livro foram todos testados, e seu funciona-
mento foi comprovado no momento da publicação do material. No entanto, a rede
é extremamente dinâmica; suas páginas estão constantemente mudando de local
e conteúdo. Assim, os editores declaram não ter qualquer responsabilidade sobre
qualidade, precisão ou integralidade das informações referidas em tais links.

Você também pode gostar