77
TECNOLOGIAS DE PROCESSAMENTO DE BIG DATA APLICADAS À MANUTENÇÃO PREDITIVA DE EQUIPAMENTOS Raphael Barros de Oliveira Santos Projeto de Graduação apresentado ao Curso de Engenharia Eletrônica e de Computação da Escola Politécnica, Universidade Federal do Rio de Janeiro, como parte dos requisitos necessários à obtenção do título de Engenheiro. Orientadores: Alexandre de Assis Bento Lima Heraldo Luís Silveira de Almeida Rio de Janeiro Fevereiro de 2017

GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

TECNOLOGIAS DE PROCESSAMENTO DE BIG DATA

APLICADAS À MANUTENÇÃO PREDITIVA DE

EQUIPAMENTOS

Raphael Barros de Oliveira Santos

Projeto de Graduação apresentado ao Curso de

Engenharia Eletrônica e de Computação da Escola

Politécnica, Universidade Federal do Rio de

Janeiro, como parte dos requisitos necessários à

obtenção do título de Engenheiro.

Orientadores:

Alexandre de Assis Bento Lima

Heraldo Luís Silveira de Almeida

Rio de Janeiro

Fevereiro de 2017

Page 2: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

ii

Page 3: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

iii

Page 4: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

iv

UNIVERSIDADE FEDERAL DO RIO DE JANEIRO

Escola Politécnica – Departamento de Eletrônica e de Computação

Centro de Tecnologia, bloco H, sala H-217, Cidade Universitária

Rio de Janeiro – RJ CEP 21949-900

Este exemplar é de propriedade da Universidade Federal do Rio de Janeiro, que

poderá incluí-lo em base de dados, armazenar em computador, microfilmar ou adotar

qualquer forma de arquivamento.

É permitida a menção, reprodução parcial ou integral e a transmissão entre

bibliotecas deste trabalho, sem modificação de seu texto, em qualquer meio que esteja ou

venha a ser fixado, para pesquisa acadêmica, comentários e citações, desde que sem

finalidade comercial e que seja feita a referência bibliográfica completa.

Os conceitos expressos neste trabalho são de responsabilidade do(s) autor(es).

Page 5: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

v

À minha família, em especial aos meus pais,

que sempre me apoiaram em todos

os momentos de minha vida.

Page 6: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

vi

AGRADECIMENTO

Primeiramente agradeço a Deus, que me acompanhou por toda esta jornada. Em

seguida, agradeço à minha família. Não há como expressar toda a gratidão que sinto por

ela, em especial aos meus pais. Tenho certeza que devo todas as minhas conquistas a eles.

Gostaria de agradecer também à minha namorada Louise, por toda a paciência e

por ter deixado meus dias mais felizes ao longo do desenvolvimento deste projeto. Um

agradecimento especial aos meus amigos, muitos deles conhecidos na faculdade. Caio,

Caio, Douglas, Marcelão, Rayssa e todos os outros que levarei para a vida inteira.

Agradeço à Radix Engenharia e Software por todo o apoio fornecido durante

minha estadia na empresa. Em especial, agradeço ao coordenador Leidson Germano e toda

a equipe de metais e mineração. Arthur, Gabriel, Rafael, Willian e muitos outros, que

tiveram paciência e me ensinaram muito mais do que eu julgava ser possível aprender em

um estágio.

Agradeço imensamente aos meus orientadores Alexandre de Assis e Heraldo Luís,

pois puderam dedicar seu tempo a este trabalho, permitindo que eu concluísse mais esta

etapa em minha vida. O apoio de vocês foi fundamental.

Finalmente, agradeço ao povo brasileiro, pois sua contribuição foi indispensável

para a minha formação. Espero retribuir este investimento depositado em mim.

Page 7: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

vii

RESUMO

Este projeto de graduação consiste no desenvolvimento de um sistema que utiliza

tecnologias de processamento de Big Data para determinar a necessidade de manutenção

de equipamentos industriais através das informações de telemetria coletadas. O sistema

foi feito utilizando, além de outras tecnologias, o Apache Spark e o SGBD Cassandra.

Técnicas de processamento paralelo e distribuído foram empregadas em seu

desenvolvimento para atingir melhor desempenho.

Palavras-Chave: Big Data, manutenção preditiva, computação paralela, computação

distribuída, Apache Spark, Cassandra, banco de dados.

Page 8: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

viii

ABSTRACT

This undergraduate project consists of the development of a system that uses

Big Data processing technologies to determine the need to maintain industrial equipment

through the collected telemetry information. The system was made using, in addition to

other technologies, Apache Spark and the Cassandra DBMS. Parallel and distributed

processing techniques were employed in its development to achieve better performance.

Key-words: Big Data, predictive maintenance, parallel computing, distributed

computing, Apache Spark, Cassandra, database.

Page 9: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

ix

SIGLAS

API – Application Program Interface

ARPANET – Advanced Research Projects Agency Network

CID – Component Identifier

CSV – Comma-separated values

DAG – Direct Acyclic Graph

ESB – Enterprise Service Busses

FMI – Failure Mode Identifier

MID – Module Identifier

ORM – Object-Relational Mapping

RDD – Resilient Distributed Dataset

SEQUEL – Structured English Query Language

SGBD – Sistemas Gerenciadores de Bancos de Dados

SMTP – Simple Mail Transfer Protocol

SQL – Structured Query Language

XML – Extensible Markup Language

Page 10: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

x

Sumário

Capítulo 1 ........................................................................................................................ 1

1.1 – Tema .................................................................................................................... 1

1.2 – Delimitação .......................................................................................................... 1

1.3 – Justificativa .......................................................................................................... 2

1.4 – Objetivos .............................................................................................................. 2

1.5 – Metodologia ......................................................................................................... 3

1.6 – Organização do documento.................................................................................. 4

Capítulo 2 ........................................................................................................................ 5

2.1 – Computação Paralela .......................................................................................... 5

2.2 – Computação Distribuída ..................................................................................... 9

2.3 – Programação Funcional ..................................................................................... 10

Capítulo 3 ...................................................................................................................... 21

3.1 – Bancos de Dados ................................................................................................ 21

3.1.1 – Bancos de Dados Relacionais ..................................................................... 21

3.1.2 – Bancos de Dados Não-Relacionais ............................................................. 23

3.1.3 – Comparações ............................................................................................... 25

3.2 – ESB .................................................................................................................... 26

3.2.1 – JBoss Fuse ................................................................................................... 27

3.3 – Linguagem Scala ................................................................................................ 27

3.4 – Apache Spark ..................................................................................................... 28

3.4.1 – Arquitetura .................................................................................................. 28

3.4.2 – Programação ................................................................................................ 30

3.5 – Telemetria dos equipamentos ........................................................................... 33

3.5.1 – Servidor VisionLink ................................................................................... 33

Capítulo 4 ...................................................................................................................... 35

4.1 – Empresas ............................................................................................................ 35

4.1.1 – Radix Engenharia e Software ...................................................................... 35

4.1.2 – Sotreq .......................................................................................................... 36

4.2 – Arquitetura ......................................................................................................... 36

4.2.1 – Configuração do cluster .............................................................................. 38

4.3 – Fontes de Informação ......................................................................................... 39

4.3.1 – Falhas .......................................................................................................... 39

4.3.2 – Padrões ........................................................................................................ 40

Page 11: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

xi

4.4 – Estrutura dos Bancos de Dados ......................................................................... 43

4.4.1 – Oracle .......................................................................................................... 43

4.4.2 – Cassandra .................................................................................................... 46

4.5 – Aplicação Spark ................................................................................................. 48

Capítulo 5 ...................................................................................................................... 52

Capítulo 6 ...................................................................................................................... 56

Bibliografia .................................................................................................................... 57

Apêndice A .................................................................................................................... 59

Page 12: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

xii

Lista de Figuras

Fig. 2.1 Lei de Moore [6] ................................................................................................. 6

Fig. 2.2 Modelo de Fork-Join [7] ..................................................................................... 7

Fig. 2.3 Paralelismo de Dados [8] .................................................................................... 8

Fig. 2.4 Lei de Amdahl [8] ............................................................................................... 9

Fig. 2.5 Comparação entre Sistemas Paralelos e Distribuídos [11]................................ 10

Fig. 2.6 Definição da interface IEnumerable .................................................................. 13

Fig. 2.7 Definição da interface IEnumerator .................................................................. 13

Fig. 2.8 Definição do método foreach ............................................................................ 14

Fig. 2.9 Aplicação do método ForEach .......................................................................... 14

Fig. 2.10 Função Map ..................................................................................................... 15

Fig. 2.11 Definição do método Map ............................................................................... 16

Fig. 2.12 Exemplo do uso de yield return ...................................................................... 16

Fig. 2.13 Exemplo do uso de Map .................................................................................. 17

Fig. 2.14 Função Filter ................................................................................................... 17

Fig. 2.15 Definição de Filter ........................................................................................... 17

Fig. 2.16 Exemplo de Filter ............................................................................................ 18

Fig. 2.17 Função Reduce ................................................................................................ 18

Fig. 2.18 Definição de Reduce ....................................................................................... 19

Fig. 2.19 Exemplo do uso de Reduce ............................................................................. 20

Fig. 3.1 Arquitetura do Spark em modo cluster [24] ...................................................... 29

Fig. 3.2 Exemplo de aplicação Spark: Contagem de IP ................................................. 32

Fig. 4.1 Arquitetura Geral do Sistema ............................................................................ 37

Fig. 4.2 Aplicação da Regra ........................................................................................... 42

Fig. 4.3 Mapeamento de PR_REGRAS ......................................................................... 45

Fig. 4.4 Mapeamento de PR_VIOLACOES ................................................................... 46

Fig. 4.5 Fluxo da Aplicação - Parte 1 ............................................................................. 49

Fig. 4.6 Fluxo da Aplicação - Parte 2 ............................................................................. 50

Fig. 4.7 Fluxo da Aplicação - Parte 3 ............................................................................. 51

Fig. 4.8 Fluxo da Aplicação - Parte 4 ............................................................................. 51

Fig. 5.1 Média de Violações por dia ............................................................................... 52

Fig. 5.2 DAG da Aplicação ............................................................................................ 53

Fig. 5.3 Linha do Tempo Estágio 1 ................................................................................ 54

Fig. 5.4 Linha do Tempo Estágio 2 ................................................................................ 55

Page 13: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

xiii

Lista de Tabelas

Tabela 3.1 Exemplo de tabela em um banco Cassandra ................................................. 24

Tabela 3.2 Comparação entre os bancos de dados utilizados [18] ................................. 25

Tabela 3.3 Exemplos de Transformações. Adaptado de [25] ......................................... 31

Tabela 3.4 Exemplos de Ações. Adaptado de [25]......................................................... 31

Tabela 4.1 Regras ........................................................................................................... 44

Tabela 4.2 Violações ...................................................................................................... 44

Tabela 4.3 Falhas dos Equipamentos ............................................................................. 47

Tabela 4.4 Falhas Temporárias ....................................................................................... 48

Page 14: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

1

Capítulo 1

Introdução

A apresentação do projeto é feita neste capítulo. Primeiramente, em 1.1, definimos

o assunto deste trabalho. Na seção 1.2, especificamos seus limites de atuação e escopo. A

motivação e justificativa são explicitadas posteriormente, em 1.3. Em seguida, os

objetivos gerais e específicos são descritos (1.4). Na seção 1.5, sintetizamos os métodos

que foram seguidos para o desenvolvimento deste projeto. Finalmente, toda a estrutura

deste documento é detalhada na seção 1.6.

1.1 – Tema

O tema deste projeto é a aplicação de tecnologias de Big Data sobre dados de

telemetria de equipamentos, mais especificamente os equipamentos fornecidos pela

Sotreq [1], empresa alvo deste trabalho. Escavadeiras, caminhões e carregadeiras estão

entre os equipamentos comercializados pela empresa.

Neste sentido, o problema a ser resolvido é criar uma aplicação e propor uma

arquitetura computacional que permita o processamento destes dados de forma escalável.

A aplicação deve ainda disponibilizar as informações úteis para o usuário de forma a

facilitar as indicações de peças e serviços para realizar a manutenção preditiva dos

equipamentos alvos.

1.2 – Delimitação

O projeto abrange apenas equipamentos com telemetria e indicativos de

necessidade de manutenção conhecidos. Técnicas de Aprendizado de Máquina e

Inteligência Artificial estão fora do escopo deste projeto.

Apesar do esforço feito em tornar a solução a mais genérica possível, o trabalho

foi realizado dentro da plataforma SotreqLink, desenvolvimento prestado pela empresa

Radix Engenharia e Software para a empresa Sotreq. Sendo assim, o projeto pode conter

Page 15: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

2

algumas particularidades das empresas envolvidas que não necessariamente seriam

aplicadas ou representariam a melhor escolha em outras ocasiões. Adicionalmente, parte

da infraestrutura e fluxo de informação deve ser utilizado para não comprometer outros

sistemas já em funcionamento.

1.3 – Justificativa

Com o crescente número de dispositivos físicos, como veículos, sensores de todo

tipo e sistemas eletrônicos embarcados, ocorre também a integração dos mesmos a rede

de computadores, permitindo a troca e envio de mensagens. Tal aumento resulta também

em grandes e, potencialmente, complexas estruturas de dados que hoje podem ser

classificados como Big Data [2].

O tratamento desses dados é de grande interesse para empresas, pois podem

fornecer informações valiosas sobre seus clientes ou equipamentos, permitindo assim um

aumento de sua produtividade. Este tratamento, no entanto, não pode ser realizado através

de abordagens tradicionais, visto que computadores comuns, trabalhando de forma

isolada, podem não possuir a capacidade de processamento necessária e computadores de

grande porte, por sua vez, podem ser financeiramente inviáveis.

Desta forma, se faz necessário o estudo de soluções alternativas à computação

tradicional para que este problema possa ser solucionado de maneira mais rápida e de

baixo custo. No nosso caso em particular, o tratamento das informações fornecidas pela

telemetria dos equipamentos pode proporcionar indicativos a respeito da necessidade de

manutenção dos mesmos, resultando em uma manutenção direcionada e,

consequentemente, mais eficaz e barata.

1.4 – Objetivos

Considerando o grande volume de dados obtidos pela telemetria dos

equipamentos, o objetivo geral é desenvolver uma solução que seja capaz de atender aos

requisitos de velocidade mínima de processamento, escalável, distribuída e ainda possa

garantir a disponibilidade destas informações para os operadores do sistema. Desta forma,

o projeto pretende cumprir os seguintes objetivos específicos:

Page 16: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

3

Utilizar os recursos computacionais disponíveis de forma eficiente

Tempo de processamento inferior à necessidade da aplicação

Arquitetura escalável permitindo o redimensionamento dos recursos

computacionais

1.5 – Metodologia

Este trabalho utiliza as informações de telemetria de equipamentos para gerar

indicativos a respeito de uma necessidade de manutenção. A partir do uso de padrões pré-

estabelecidos de telemetria, pretende-se identificá-los ao longo da operação do

equipamento alvo e assim disponibilizar para o usuário a ocorrência desses padrões.

Desta forma, foi decidido recolher junto aos técnicos competentes, e usuários

desta aplicação, os padrões de telemetria a serem encontrados. Cada técnico deverá,

portanto, adicionar e editar neste sistema o que julgar conveniente para a manutenção dos

equipamentos.

Posteriormente, foram estudadas e escolhidas as arquiteturas e ferramentas

computacionais para serem utilizadas no desenvolvimento do projeto, tendo sempre em

consideração as delimitações e objetivos expostos anteriormente.

Para atender o objetivo de garantir a disponibilidade das informações, estas

deverão ser armazenados de forma distribuída. É importante ressaltar que a

disponibilidade dos dados é um problema crescente em grandes redes de computadores.

Assim, a arquitetura escolhida deverá minimizar a existência de um Ponto Único de Falha

(SPOF – Single Point of Failure) [3].

Após a escolha das ferramentas, foi realizado o desenvolvimento da lógica de

programação da aplicação. Esta utilizou, principalmente, técnicas de computação

distribuída. Desta forma, técnicas de transformações de dados (mapeamentos, filtros,

reduções) utilizadas em processamento de Big Data foram preferencialmente

empregadas.

Page 17: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

4

O trabalho terá obtido êxito ao conseguir criar uma aplicação que identifique os

padrões de erro a serem encontrados nos dados de telemetria e os disponibilize para o

usuário realizar as intervenções que julgar necessárias. É preciso ainda que a aplicação

atenda aos requisitos de paralelização e velocidade do processamento, alta

disponibilidade e rápido acesso aos dados obtidos.

1.6 – Organização do documento

No capítulo 2 discutimos os conceitos de computação paralela e distribuída,

evidenciando as vantagens de seu uso. Fazemos uma introdução ao paradigma de

programação funcional.

No capítulo 3 são descritas as tecnologias utilizadas neste projeto, incluindo

bancos de dados, linguagens de programação e motores de processamento.

No capítulo 4 está contido o desenvolvimento da aplicação, assim como a

arquitetura geral dos servidores e a modelagem dos bancos de dados.

No capítulo 5 é apresentada uma síntese dos resultados, obtidos principalmente

através de consultas ao banco de dados e análise das métricas fornecidas pelo motor de

processamento.

No capítulo 6 são sintetizadas as conclusões deste projeto, comparando os

resultados obtidos com os objetivos planejados.

Page 18: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

5

Capítulo 2

Computação Paralela e Distribuída e

Programação Funcional

Com o aumento da quantidade e complexidade dos dados e tarefas

computacionais, alternativas à computação sequencial tradicional estão cada vez mais em

evidência. Apesar de essas discussões datarem da década de 1960, elas se tornaram mais

populares a partir da década de 2000. O barateamento de computadores de uso geral, o

aumento do número de núcleos em um processador e a oferta de serviços de computação

em nuvem contribuíram significativamente para o crescimento do uso destas tecnologias.

Nesta sessão são discutidas, principalmente, duas alternativas que podem ser

utilizadas de forma combinada ou isolada: Computação Paralela e Computação

Distribuída.

2.1 – Computação Paralela

Tradicionalmente, softwares de computadores foram escritos para computação

sequencial. Nesta arquitetura, uma única instrução é executada de cada vez e, após o

término de uma instrução, a próxima é executada. Sendo assim, a frequência de operação

de um processador era o principal fator que determinava a velocidade de processamento

do mesmo. Com o objetivo de melhorar a performance de seus processadores, os

fabricantes investiram principalmente no aumento de sua frequência.

O aumento da frequência dos processadores foi dominante desde meados da

década de 1980 até o início dos anos 2000, quando limitações físicas impediram um

aumento ainda maior. Uma das principais limitações a este aumento é a potência dissipada

pelo processador, que é proporcional a sua frequência de operação, além de outros fatores

[4]. Portanto, o escalamento da frequência se tornava uma opção não mais viável para o

melhoramento dos processadores, o que incentivou o estudo de alternativas.

Page 19: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

6

De acordo com a Lei de Moore (Fig. 2.1), que ainda se encontra em vigência, o

número de transistores em um microprocessador dobra a cada período de 18 a 24 meses

[5]. Desta forma, os fabricantes de microprocessadores decidiram não utilizar estes

transistores adicionais para escalar a frequência, e sim para adicionar processamento

paralelo, na forma de novos núcleos de processamento. A partir de então, processadores

de múltiplos núcleos têm a capacidade de executar computação paralela.

Fig. 2.1 Lei de Moore [6]

Um padrão de projeto típico de programas paralelos é o modelo de Fork-Join,

como pode ser visto na Fig. 2.2. Este modelo consiste em, a partir de um programa

sequencial, identificar tarefas que têm potencial para serem executadas simultaneamente

e as separar, realizando a operação de Fork. Após o término de todas as tarefas, o

programa reúne os resultados com uma operação de Join, para seguir assim seu fluxo

sequencial.

Page 20: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

7

Fig. 2.2 Modelo de Fork-Join [7]

Existem diversas formas de computação que podem ser classificadas como

paralela. Estas formas incluem paralelismo em nível de bits, instruções, tarefas. Também

é possível realizar paralelismo distribuindo a informação em diferentes computadores, o

que é discutido na sessão seguinte. Para fim de simplicidade e para manter o escopo deste

documento, discutimos aqui a forma de paralelização utilizada neste projeto:

Paralelização de Dados.

Nesta forma de paralelização, estruturas de dados regulares, contendo o mesmo

tipo de dado e tendo tamanhos conhecidos, podem ser divididas igualmente entre os

processadores e/ou seus respectivos núcleos1. Cada núcleo, portanto, realiza a mesma

operação sobre os dados, o que pode diminuir drasticamente o tempo de processamento

total da tarefa. A Fig. 2.3 ilustra este procedimento.

Para exemplificar este funcionamento, será considerada uma coleção contendo n

elementos. Supõe-se ainda que seja necessário realizar a mesma operação em todos os

elementos da coleção com o tempo de processamento por elemento igual a 𝑇𝑒. Em um

programa sequencial, o tempo total de processamento seria, portanto, igual a 𝑛 ∗ 𝑇𝑒.

Porém, em um processador com m núcleos, a mesma tarefa poderia ser dividida entre os

núcleos para ser executada simultaneamente. Assim o tempo total em um programa

paralelo, excluindo os tempos de particionamento e reunião dos dados, seria, idealmente,

igual a 𝑡𝑒𝑡𝑜 (𝑛

𝑚) ∗ 𝑇𝑒

1 Existem outras formas de particionamento de dados quando o tamanho não é conhecido. Uma referência

pode ser encontrada em [24].

Page 21: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

8

Fig. 2.3 Paralelismo de Dados [8]

Evidenciando o aumento da velocidade de processamento em programas

paralelos, a Lei de Amdahl [9] relaciona o ganho de velocidade na execução de toda a

tarefa com o aumento de velocidade promovido por recursos adicionais e a proporção do

tempo de execução que se aproveita por recursos adicionais. De forma simplificada,

tempos a equação:

𝑆𝑙𝑎𝑡ê𝑛𝑐𝑖𝑎(𝑠) =

1

(1 − 𝑝) +𝑝𝑠

(2.1)

Em nosso caso simplificado, 𝑆𝑙𝑎𝑡ê𝑛𝑐𝑖𝑎 é o aumento total de velocidade da tarefa, 𝑠 é o

número de processadores (ou núcleos) e 𝑝, a proporção da tarefa que pode ser

paralelizada. É interessante notar que esta Lei nos mostra que o limite superior para o

aumento de velocidade de uma tarefa é limitado pela parte serial, ou que não pode ser

paralelizada (1-p). Assim, se a proporção paralela de uma tarefa corresponde a 80% do

tempo de processamento, o limite máximo teórico do ganho de velocidade se dá quando

tomamos o limite de 𝑠 tendendo ao infinito, tendo como nesse caso um ganho de 5 vezes

a velocidade. A Lei de Amdahl mostra o potencial que o paralelismo pode ter em uma

aplicação, como mostra a Fig. 2.4.

Page 22: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

9

Fig. 2.4 Lei de Amdahl [8]

2.2 – Computação Distribuída

Sistemas distribuídos estão presentes desde o final da década de 1960 e início da

década de 1970. A sua utilização teve início principalmente em redes locais e foi

expandida pela ARPANET com a distribuição de servidores pelos Estados Unidos. A sua

aplicação de maior sucesso e o primeiro exemplo de aplicação distribuída em larga-escala

foi o e-mail, principal incentivo da expansão da ARPANET para a formação da Internet.

Hoje em dia, diversas aplicações são construídas sobre sistemas distribuídos, que vão

desde a transferências de arquivos via FTP até jogos multijogadores online.

Um sistema distribuído pode ser definido um conjunto de computadores

conectados em rede que se comunicam e coordenam suas tarefas através de troca de

mensagens [10]. Com o fim de manter o escopo deste documento, são discutidos apenas

os aspectos de sistemas distribuídos relacionados com este projeto, especialmente no que

tange à Computação Paralela.

A principal diferença entre um sistema paralelo e um distribuído é a memória.

No já visto Sistema Paralelo, todos os processadores (ou núcleos) têm acesso à mesma

memória, ou seja, apresenta memória compartilhada. Entretanto, um sistema distribuído

Page 23: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

10

opera com um conjunto de computadores onde cada nó da rede acessa somente a sua

memória interna, caracterizando assim a memória distribuída. Esta característica é

importante de deve ser considerada no desenvolvimento da aplicação, como será visto

adiante. A Fig. 2.5 ilustra a comparação entre sistemas distribuídos e paralelos.

Fig. 2.5 Comparação entre Sistemas Paralelos e Distribuídos [11]

O uso de Sistemas distribuídos possui ainda algumas vantagens sobre o uso de um

computador de grande porte, em especial no contexto deste projeto de processamento de

Big Data:

Escalabilidade de Recursos Computacionais

Economicamente mais acessível

Redução do risco de Single Point of Failure

Facilidade de Manutenção

É importante lembrar que essas caraterísticas vão ao encontro dos requisitos do

projeto discutidos no Capítulo I, especialmente a escalabilidade dos recursos

computacionais.

2.3 – Programação Funcional

Programação funcional pode ser definida como um tipo de Paradigma de

Programação, ou seja, um estilo ou forma de se estruturar os elementos de um programa

Page 24: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

11

de computador. Este estilo enfatiza o uso de funções matemáticas em detrimento de

afirmações, como atribuições e chamadas de retorno.

Este paradigma foi fundado sobre o sistema de Lambda Cálculo de 1932, sistema

lógico-matemático que estuda principalmente as funções recursivas. Para manter o

escopo deste documento, são detalhados apenas os aspectos mais relevantes que foram

utilizados neste projeto. O artigo original pode ser visto em [12].

Como dito anteriormente, o estilo funcional de programação se utiliza

primariamente da avaliação de funções. E, para tal, é comumente utilizada também uma

outra notação. Tradicionalmente, podemos declarar a função identidade na forma:

𝐼𝑑𝑒𝑛𝑡𝑖𝑑𝑎𝑑𝑒(𝑥) = 𝑥 (2.2)

Por outro lado, a programação funcional nos permite declarar funções que não são

nomeadas. Estas funções são muito úteis e foram largamente utilizadas neste projeto. Elas

aceleram o desenvolvimento e contribuem para um melhor entendimento do código

escrito. Estas são chamadas de Funções Anônimas e podem ser escritas utilizando a

notação lambda na forma:

𝑥 → 𝑥 (2.3)

O termo à esquerda do operador lambda (→) é o argumento da função, enquanto

à sua direita temos o retorno da função. No caso da função identidade, ela apenas retorna

o próprio argumento, não realizando nenhuma operação significativa. Podemos ainda

declarar funções com múltiplos argumentos, como segue:

(𝑥, 𝑦) →𝑥

2+𝑦

2

(2.4)

Temos, portanto, que a função acima retorna a média aritmética de dois números.

A princípio, o uso de funções anônimas simplesmente nos permite omitir seu

identificador, mas não obtemos vantagem com isso. Sem o seu nome, não poderíamos

Page 25: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

12

chamar a função em outros locais do programa, gerando uma grande perda de reuso de

código e dificultando o desenvolvimento como um todo.

Entretanto, o uso de funções anônimas se torna uma ferramenta muito poderosa

se utilizada em conjunto com um outro conceito da programação funcional: Funções de

Alta Ordem. De maneira geral, funções de alta ordem são funções que podem receber

outras funções como argumentos e/ou retornar outras funções como resultado [13]. Um

exemplo disso no cálculo matemático é o operador diferencial, que tem como argumento

uma função e retorna outra.

Utilizando desta propriedade, podemos escrever uma função como na forma que

segue:

(𝑥, 𝑦) → 𝑥(𝑦) (2.5)

Temos agora uma mudança fundamental em relação às funções mostradas

anteriormente. Observa-se que agora o argumento 𝑥 não é mais um valor e sim uma outra

função. Neste caso, a função anônima acima apenas aplica uma outra função passada

como argumento em 𝑥 ao valor passado em 𝑦 e retorna seu resultado.

O uso de funções de alta ordem nos permite escrever funções ou, dentro do

paradigma de Programação Orientada a Objetos, métodos que possam ser aplicadas em

estruturas de dados que cumpram certos pré-requisitos. Particularmente, o uso de funções

de alta ordem é muito útil em padrões de projeto do tipo Iterador, que implementam o

processo de Iteração a ser executado em uma coleção.

Na linguagem de programação C#, que foi utilizada neste projeto para

desenvolver a aplicação de servidor que interage com o usuário, a interface IEnumerable

é responsável por retornar um Iterador, como pode ser vista na sua definição na Fig. 2.6:

public interface IEnumerable {

IEnumerator GetEnumerator(); }

Page 26: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

13

Fig. 2.6 Definição da interface IEnumerable

Observa-se que o único método que deve ser implementado nesta interface é o

GetEnumerator(), que irá retornar uma outra interface IEnumerator. Esta interface, em

C#, é quem define os métodos que deverão ser implementados por um Iterador. Desta

forma, todo objeto que implementa a interface IEnumerable pode ser iterado e utilizado

em laços de repetição do tipo foreach. A definição da interface IEnumerator nos mostra

os métodos e propriedades que precisam ser implementadas por um Iterador, como é visto

na Fig. 2.7:

public interface IEnumerator {

object Current { get; } bool MoveNext(); void Reset();

}

Fig. 2.7 Definição da interface IEnumerator

Temos, portanto, que o Iterador precisa implementar os métodos MoveNext e

Reset, além de disponibilizar a propriedade Current. O método Reset tem a função de

posicionar o Iterador imediatamente antes do início da coleção em questão. O método

MoveNext avança o Iterador para o próximo elemento da coleção, retornando o valor

lógico “verdadeiro” caso exista um objeto na nova posição. Se o Iterador chegar ao fim

da coleção e nenhum objeto for encontrado, o método retorna “falso”. A propriedade

Current apenas disponibiliza o elemento atual do Iterador.

Sabendo agora a definição das interfaces IEnumerable e IEnumerator e

utilizando-se do suporte de C# para funções de alta ordem, podemos escrever um método

de extensão para a interface IEnumerable que realiza a operação de foreach, ou seja,

realiza uma operação para cada elemento da coleção. O método pode ser visto na Fig. 2.8.

Page 27: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

14

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {

IEnumerator<T> enumerator = source.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext())

action(enumerator.Current); }

Fig. 2.8 Definição do método foreach

Como pode ser visto, o método de extensão ForEach recebe como argumentos a

própria coleção em source e uma ação em action, que nada mais é que a sintaxe da

linguagem C# para uma função sem retorno. O método acima apenas executa a função

Reset para garantir que o Iterador se encontra no início da coleção e executa o método

MoveNext para atravessar toda a coleção enquanto forem encontrados elementos. Por fim,

a função passada como argumento é aplicada em cada elemento da coleção.

O método ForEach definido acima é um típico caso de uso de funções de alta

ordem. É muito conveniente utilizá-lo em conjunto com funções anônimas durante o

desenvolvimento de um programa. Um exemplo de sua utilização pode ser vista na Fig.

2.9:

int[] collection = new int[] { 1, 2, 3, 4, 5}; collection.ForEach(x => Console.WriteLine(x));

//Resultado: //1 2 3 4 5

Fig. 2.9 Aplicação do método ForEach

É importante notar que, como o método de extensão foi realizado em uma

interface genérica, podemos utilizá-lo em todos os objetos que a implementam, neste caso

um Array. O mesmo método poderia ser utilizado em filas, listas, pilhas ou quaisquer

estruturas de dados que implementem a interface IEnumerable. Isto permite reuso de

código, abstração e outros benefícios que são discutidos adiante. A notação lambda se

torna agora vantajosa, pois não precisamos declarar uma função “Imprimir” para poder

ser usada como argumento e imprimir todos os valores da coleção, o que contribui para

um código mais limpo e inteligível.

Page 28: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

15

Existem ainda muitas outras operações que podem ser aplicadas sobre coleções.

Além da já discutida operação foreach, que realiza uma ação sobre cada objeto da

coleção, diversas funções genéricas podem ser implementadas da mesma forma. A seguir

serão discutidas três dessas operações mais comuns: Map, Filter e Reduce.

A função Map, como o próprio nome diz, consiste em mapear todos os elementos

de uma coleção (o domínio) para o conjunto imagem correspondente da função que é

passada como argumento. Portanto, seja uma função 𝑓: 𝑋 → 𝑌 o argumento de Map, a

coleção original composta por um subconjunto de 𝑋 é transformada em um subconjunto

de 𝑌 composto pela imagem de cada elemento do domínio 𝑋. A Fig. 2.10 exemplifica a

aplicação de Map.

[ 𝑥1𝑥2𝑥3𝑥4𝑥5] 𝑓:𝑋→𝑌→

[ 𝑓(𝑥1)𝑓(𝑥2)𝑓(𝑥3)𝑓(𝑥4)𝑓(𝑥5)]

Fig. 2.10 Função Map

Assim como foi feito no exemplo anterior, podemos utilizar um Iterador para

percorrer uma coleção e aplicar a função do argumento de Map em cada elemento. Como

resultado, o método Map retornará uma nova coleção contendo os elementos da imagem

da função do argumento, de acordo com a definição do parágrafo anterior. O método Map

pode ser implementado da mesma forma que o exemplo de ForEach, utilizando a interface

IEnumerable, como pode ser visto na Fig. 2.11:

public static IEnumerable<TResult> Map<TSource,TResult>(this IEnumerable<TSource> source, Func<TSource,TResult> function) {

IEnumerator<TSource> enumerator = source.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext())

yield return function(enumerator.Current); }

Page 29: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

16

Fig. 2.11 Definição do método Map

O método Map, assim como o ForEach, recebe uma interface IEnumerable source

de tipo genérico TSource. Porém, desta vez, Map retorna uma outra interface de tipo

genérico TResult. Como esperado, a função do argumento de Map também deve ter os

mesmos tipos de entrada e saída respectivamente, como pode ser visto pelo tipo da função

Func<TSource,TResult>. Da mesma forma que ForEach, Map usa um Iterador para

percorrer a coleção, e retornar o resultado da função function aplicada em cada elemento.

A diferença aqui se encontra na sintaxe yield return de C#. Diferente de um return

comum, yield return não representa um retorno único do método Map e sim o retorno de

cada elemento formando uma coleção. Desta forma, Map apresenta vários pontos de

retorno. A Fig. 2.12 ilustrar o uso de yield return.

public static IEnumerable<int> Inteiros() {

yield return 1; yield return 2; yield return 3; yield return 4; yield return 5;

} public static void Executar() {

IEnumerable<int> inteiros = Inteiros(); inteiros.ForEach(x => Console.WriteLine(x)); //Resultado: //1 2 3 4 5

}

Fig. 2.12 Exemplo do uso de yield return

Podemos observar que o método Inteiros() apresenta várias linhas com a sintaxe

yield return. Cada linha retorna um elemento da coleção, neste caso apenas um inteiro. O

método Map funciona da mesma forma: enquanto o enumerador retornar verdadeiro para

o método MoveNext(), Map irá invocar yield return, retornando assim elemento por

elemento da nova coleção. Adiante, temos um exemplo do uso de Map (Fig. 2.13), onde

cada valor da coleção original é mapeado para o seu dobro.

Page 30: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

17

int[] collection = new int[] { 1, 2, 3, 4, 5 }; collection.Map(x => x*2).ForEach(x => Console.WriteLine(x)); //Resultado: //2 4 6 8 10

Fig. 2.13 Exemplo do uso de Map

A próxima operação sobre coleções que será discutida é Filter. Como o próprio

nome indica, Filter consiste em aplicar um filtro sobre todos os elementos da coleção,

retornando apenas os elementos que passarem pelo filtro especificado. Portanto, seja a

função 𝑓: 𝑋 → 𝐵 o argumento de Filter, B um booleano e a coleção original composta por

elementos do tipo 𝑋, a coleção retornada por Filter será formada pelos mesmos elementos

da coleção original que retornarem verdadeiro quando 𝑓 for aplicado em seus elementos.

A Fig. 2.14 ilustra o uso de Filter.

[ 𝑥1𝑥2𝑥3𝑥4𝑥5] 𝑓:𝑋→𝐵→ [

𝑥1𝑥4𝑥5]

Fig. 2.14 Função Filter

Uma implementação pode ser feita a partir das mesmas estruturas de dados

utilizadas em Map, assim como o uso da interface IEnumerable e da sintaxe especial yield

return. A implementação pode ser vista na Fig. 2.15.

public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Func<T,bool> test) {

IEnumerator<T> enumerator = source.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext()) if (test(enumerator.Current)) yield return enumerator.Current; }

Fig. 2.15 Definição de Filter

Page 31: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

18

Como pode ser visto, Filter recebe como argumento, além da própria coleção do

tipo genérico T, uma função teste que avalia cada elemento de source e retorna um valor

booleano. Aqueles elementos em que a função teste retornar verdadeiro como resultado,

serão retornados para a nova coleção utilizando-se yield return. A seguir, temos um

exemplo da utilização de Filter (Fig. 2.16), onde a condição de que o elemento deve ser

maior que 2 é passada como argumento.

int[] collection = new int[] { 1, 2, 3, 4, 5 }; collection.Filter(x => x > 2).ForEach(x => Console.WriteLine(x)); //Resultado: //3 4 5

Fig. 2.16 Exemplo de Filter

Finalmente, temos a última operação que será discutida nesta sessão: Reduce. O

método de redução é significativamente diferente dos métodos Map e Filter apresentados

anteriormente. Apesar de Reduce também utilizar um Iterador para percorrer uma

coleção, o objetivo de Reduce não é retornar uma nova coleção e sim único objeto que

contenha alguma informação significativa da coleção, como visto na Fig. 2.17. Portanto,

Reduce realiza um mapeamento de todo um conjunto para um único elemento. Um

exemplo de operação de mesma natureza é o determinante de matrizes, que a partir do

conjunto de números da matriz, calcula-se um único valor que a representa.

[ 𝑥1𝑥2𝑥3𝑥4𝑥5] 𝑓:𝑋2→𝑋→ 𝑥𝑎

Fig. 2.17 Função Reduce

Para realizar uma operação de redução, além de um Iterador, utiliza-se também

um Acumulador. Acumuladores são estruturas responsáveis por armazenar resultados

intermediários de operações de uma Iteração. Fazendo uma associação com o exemplo de

Page 32: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

19

determinante exibido anteriormente, este pode ser determinado por um somatório de

produtos. Assim, o acumulador poderia armazenar o resultado do primeiro produto e, a

cada novo produto, somar o seu próprio valor ao novo produto, realizando a acumulação.

Desta forma, o método Reduce precisa definir exatamente como essa acumulação

deve ser realizada. Isto é feito definindo-se uma outra função, que deve ser passada como

argumento a Reduce. Em contraste com os métodos Map e Filter, onde esta função tinha

apenas um argumento (o elemento da coleção), a função argumento de Reduce deve ter

dois argumentos: um para o acumulador e outro para o elemento corrente. Como o

resultado da função será usado para incrementar o acumulador, o próprio acumulador, o

elemento corrente e o retorno da função devem ser do mesmo tipo. Assim, esta função

deve ser da forma 𝑓: 𝑋2 → 𝑋. Uma implementação do método Reduce pode ser vista na

Fig. 2.18.

public static T Reduce<T>(this IEnumerable<T> source, Func<T, T, T> funcao) {

T accumulator; IEnumerator<T> enumerator = source.GetEnumerator(); enumerator.Reset(); if (!enumerator.MoveNext()) //Se o iterador for vazio, retorna o padrão do tipo

return default(T); accumulator = enumerator.Current; while (enumerator.MoveNext())

accumulator = funcao(accumulator, enumerator.Current); return accumulator;

}

Fig. 2.18 Definição de Reduce

De acordo com o que foi dito anteriormente, o método Reduce retorna agora om

objeto do tipo T em vez de um IEnumerable<T>, como era nos casos de Map e Filter.

Outra diferença significativa é a função argumento, que agora possui dois argumentos,

sendo o primeiro o acumulador e o segundo o elemento corrente. A palavra chave default

retorna o padrão do tipo T e sua referência pode ser encontrada em [14]. É importante

notar que o acumulador é o destino da função passada como argumento a Reduce. Por

fim, Reduce retorna o próprio acumulador. A Fig. 2.19 ilustra um exemplo de sua

aplicação.

Page 33: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

20

int[] collection = new int[] { 1, 2, 3, 4, 5 }; int sum = collection.Reduce((acc, x) => acc + x); Console.WriteLine(sum); //Resultado: 15 int prod = collection.Reduce((acc, x) => acc * x); Console.WriteLine(prod); //Resultado: 120

Fig. 2.19 Exemplo do uso de Reduce

Em seu primeiro uso, o acumulador está sendo somado com o elemento corrente,

assim o método Reduce retorna o somatório de todos os elementos da coleção. Já em seu

segundo uso, o acumulador é multiplicado com o elemento corrente, logo Reduce retorna

o produtório da coleção.

Concluindo esta sessão sobre programação funcional, pode-se observar um pouco

da utilidade deste paradigma de programação, assim como o uso de funções anônimas e

de Alta Ordem. Além de nos fornecer maior facilidade de desenvolvimento, leitura e

limpeza do código, as ferramentas fornecidas por este paradigma nos fornecem um alto

grau de abstração e permite que os desenvolvedores tenham foco nas tarefas mais

importantes. Existem muitas bibliotecas que implementam as operações sobre coleções

descritas acima (e muitas outras), possibilitando que a atenção do desenvolvedor altere

de como fazer para o que fazer. Assim, é permitido que o desenvolvedor tenha uma

abstração maior sobre quais transformações em coleções devem ser feitas em vez de como

realizá-las, através de um laço for por exemplo. É importante ressaltar ainda que a própria

natureza das operações sobre coleções tem um grande potencial para paralelismo. Pode-

se observar, por exemplo, que a execução de Map não está atrelada a um algoritmo

sequencial. De fato, podemos aplicar a função passada como argumento de Map

simultaneamente em todos os elementos a ainda obteríamos o mesmo resultado, pois o

resultado do mapeamento de um elemento não depende de outro. O mesmo ocorre para

as funções Filter e Reduce. Não é surpresa que muitas bibliotecas que implementam

paralelismo utilizam-se de programação funcional para expor suas ferramentas ao

desenvolvedor. Todas estas vantagens contribuem para uma menor complexidade de

programação, maior facilidade de manutenção e, principalmente, menor tempo de

desenvolvimento, o que é de nosso interesse enquanto desenvolvedores.

Page 34: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

21

Capítulo 3

Tecnologias Utilizadas

Neste capítulo são descritas as diversas tecnologias empregadas neste trabalho.

Na sessão 4.1 discorremos sobre os bancos de dados e os diferentes modelos existentes.

Em 4.2, definimos o que é um ESB e exemplificamos as vantagens de sua utilização. A

linguagem Scala é apresentada em 4.3, seguida pela máquina de processamento Spark em

4.4. Finalmente, o capítulo é encerrado descrevendo o processo de aquisição de dados dos

equipamentos.

3.1 – Bancos de Dados

Grandes quantidades de dados, para serem analisados, exigem uma maneira

confiável e segura de armazenamento e manipulação. Para isso, foram desenvolvidos

diversos esquemas de bancos de dados. Um banco de dados é definido como uma coleção

de dados organizada e modelada de forma conveniente objetivando a aplicação em que

será utilizada.

Existem pelo menos duas grandes categorias de banco que foram usados neste

projeto. Da categoria de bancos de dados relacionais, foi utilizado o Sistema

Gerenciador de Bancos de Dados (SGBD) Oracle, enquanto na categoria de bancos de

dados não relacionais foi utilizado o SGBD NoSQL (não somente SQL) Cassandra.

3.1.1 – Bancos de Dados Relacionais

Bancos de dados relacionais, cuja origem data da década de 1970, modelam

objetos na forma de tuplas de valores armazenadas em Relações (representadas como

tabelas). Cada relação possui um Esquema, que determina a estrutura de suas tuplas. Esses

bancos modelam relacionamentos entre dados de forma explícita, através da utilização de

chaves estrangeiras, que relacionam uma ou mais colunas de uma tabela com colunas de

outra, ligando assim tuplas que se relacionam.

Page 35: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

22

A origem desse modelo de banco pode ser lida em [15]. Seus paradigmas

principais são a separação da estrutura interna de armazenamento de dados da forma com

que estes dados são exibidos nas aplicações que os utilizam. Uma das primeiras

linguagens desenvolvidas para este modelo relacional, com o objetivo de obter e

manipular dados, foi a SEQUEL (Structured English Query Language) [16]. Neste artigo,

o autor introduz o conceito de uma linguagem universal para operações em dados, o que

veio a se tornar o que hoje conhecemos como SQL (Structured Query Language, ou

Linguagem de Consulta Estruturada).

3.1.1.1 – SQL

SQL é uma linguagem utilizada para inclusão, obtenção, modificação e exclusão

de dados. Ela se baseia no conceito de operações sobre conjuntos: ao invés de loops

explícitos, utiliza-se uma linguagem declarativa para descrever a operação que se deseja

executar, deixando para o SGBD a reponsabilidade de transformá-las em operações

explícitas (Álgebra Relacional). SQL começou a ser desenvolvida também na década de

1970 e passo por inúmeras adições e padronizações até chegar a forma que se tem hoje.

3.1.1.2 – ORM

Uma ferramenta utilizada para se trabalhar com bancos relacionais são as

chamadas ORMs (Object-Relational Mapping, ou mapeamentos objeto-relacionais) que

convertem relações de um banco de dados para objetos (transformando relações em listas

de objetos) de linguagem orientada a objetos. Nesse projeto utilizamos o Entity

Framework, que é uma biblioteca para ADO.NET de conversão de dados em bancos

Relacionais para objetos em C#.

Bancos relacionais são padrões em praticamente todo tipo de indústria e são os

mais utilizados como bancos de dados para propósitos gerais. Entretanto esse tipo de

banco de dados tem diversas deficiências, das quais podemos citar:

Bancos de dados relacionais tradicionais trabalham bem com um volume

moderado de dados (centenas de milhares e até alguns milhões de objetos), mas

perdem eficiência para volumes maiores. Por exemplo, os dados vindos dos

Page 36: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

23

sensores de uma única máquina moderna podem chegar na casa dos milhões em

apenas um dia, o que é uma característica de aplicações de Big Data;

De forma semelhante, esses bancos não são eficientes para efetuar operações

(filtragem, soma, etc.) em volumes de dados desta magnitude;

Bancos de dados relacionais têm problemas para manter alta disponibilidade e

consistência de dados quando utilizados na forma de sistemas distribuídos por um

número muito grande de nós, típicos em aplicações de Big Data.

3.1.2 – Bancos de Dados Não-Relacionais

Bancos de dados não relacionais sempre estiveram presentes, mas sua

popularidade tem crescido no cenário atual de desenvolvimento de software pelo aumento

da utilização de Big Data devido ao grande volume de dados complexos sendo obtidos e

gerados por todas as áreas da indústria. Outro fator relevante para sua popularidade é seu

uso cada vez mais frequente em sistemas distribuídos. É mais economicamente viável o

uso de vários computadores conectados em rede (local ou internet) em comparação com

a manutenção de um único servidor centralizado.

3.1.2.1 – Cassandra

Apache Cassandra é um SGBD de código-aberto NoSQL criado para a

manipulação e consulta de um alto volume de dados de forma distribuída, onde cada nó

do sistema funciona de forma simétrica (isto é, sem necessidade de um mestre). As

informações presentes nessa seção foram retiradas principalmente da documentação do

Cassandra do site da DATASTAX [17], que é um distribuidor de uma versão proprietária

do Cassandra. Neste projeto, foi utilizada a distribuição open-source do software, assim

como a documentação da Datastax e seus softwares livres como o DevCenter para a

visualização de dados.

Se por um lado o Cassandra não fornece diretamente informações estatísticas ou

de agregações sobre os dados inseridos, a sua capacidade de armazenamento e obtenção

de dados pode alcançar a marca de bilhões de registros, sendo esta uma de suas principais

vantagens.

Page 37: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

24

O funcionamento do armazenamento de dados nesse banco de dados se assemelha

à utilização da estrutura de dados Dicionário, presente na maioria das linguagens de

programação. Os dados são armazenados com chaves (que podem ter múltiplas colunas)

e os valores são obtidos através dessas chaves (tendo necessidade de obter informações

sobre os dados presentes, é preciso iterar por todo o conjunto de dados, o que é ineficiente

e custoso).

No exemplo a seguir, descrevemos simplificadamente o funcionamento do uso

das chaves do banco Cassandra. Deseja-se armazenar informações sobre sensores de um

equipamento, o que foi feito de acordo com a Tabela 3.1.

Chave Valor

Número de Série Sensor Data Medição Unidade

AAA001 Temperatura 18/11/2016 300 K

AAA001 Temperatura 19/11/2016 305 K

AAA001 Velocidade 18/11/2016 36 km/h

AAA002 Temperatura 21/11/2016 298 K

AAA002 Pressão 21/11/2016 11200 Pa

Tabela 3.1 Exemplo de tabela em um banco Cassandra

O acesso aos valores só pode ser feito utilizando as chaves de forma sequencial.

Primeiramente devemos determinar a chave para o número de série. Se precisarmos de

uma consulta mais específica, podemos determinar a chave para o sensor. Consultas

possíveis neste banco seriam:

Obter todos os dados de sensores de todos os equipamentos;

Obter todos os dados dos sensores do equipamento AAA001;

Obter todos os dados dos sensores de temperatura do equipamento AAA001.

Por outro lado, as seguintes consultas não poderiam ser feitas diretamente pelo

Cassandra:

Obter todos os sensores de temperatura de todos os equipamentos;

Page 38: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

25

Obter todos os sensores de temperatura do equipamento AAA001 com

medição abaixo de 300 K;

Contagem do total de dados da tabela (para grande quantidade de dados).

A solução padrão para essas dificuldades é a replicação de dados: os dados de

cada tabela são também inseridos em outras tabelas, cada uma com uma chave apropriada

para a execução de uma consulta específica. Além da definição das tabelas, é importante

tomar cuidado com a sua fragmentação, ou seja, com a forma através da qual elas serão

subdivididas entre os nós.

3.1.3 – Comparações

Na Tabela 3.2temos algumas diferenças significativas entre os bancos discutidos

anteriormente.

Oracle Cassandra

Tipo SGBD Relacional SGBD Não Relacional

Orientado a Colunas

Licença Comercial Open-source

Implementação C e C++ Java

Tipada Sim Sim

Linguagem SQL CQL

Método de Fragmentação2 Horizontal Sharding

Consistência3 Imediata Eventual

Quantidade de dados4 Moderada Alta

Velocidade de inserção4 Alta Baixa

Velocidade de Obtenção4 Moderada Alta

Tabela 3.2 Comparação entre os bancos de dados utilizados [18]

2 Como o conjunto de dados é divido em disco e/ou memória 3 Momento em modificações serão alteradas em todo o sistema após a transação 4 Dados comparativos

Page 39: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

26

3.2 – ESB

Como já mencionado neste documento, este projeto faz parte de uma plataforma

maior que integra diversos módulos, cada qual com o seu funcionamento interno distinto.

Desta forma, se faz necessária a utilização de alguma plataforma integradora para mediar

a comunicação entre os diversos sistemas, evitando realizar uma integração para cada

combinação de módulos se comunicarem diretamente entre si.

ESBs (Enterprise Service Busses ou Barramentos de Serviços) são padrões de

arquitetura de software para a implementação de múltiplos serviços que se comunicam

mutuamente. As discussões apresentadas aqui são baseadas em [19].

ESBs são uma arquitetura orientada a serviços. Múltiplos produtores e

consumidores oferecem e consomem serviços. Cada um deles compõe um “bloco” no

sistema. Esses blocos se comunicam através de mensagens, compostas de um header –

meta-dados sobre a mensagem enviada, sobre o fluxo que ela deve seguir e sobre o

formato dos dados contidos, e um body – os dados da mensagem em si. Essas mensagens

trafegam em um barramento, onde estão as interconexões desses sistemas.

Para exemplificar a vantagem do uso de ESBs, é descrita uma integração típica de

sistemas. Seja uma aplicação, denominada Consumidor 1, que deseja se conectar a um

serviço SMTP de e-mails. Ao invés de fazê-lo diretamente (através de bibliotecas), a

aplicação se conecta a um método do ESB que envia o e-mail diretamente, chamado

Produtor 1. A princípio, a complexidade aumentou e nada foi ganho. Se houver uma outra

aplicação, nomeada Consumidor 2, ela poderá utilizar o serviço presente no barramento.

Agora supomos que o primeiro serviço deseja também acessar uma aplicação Web

(Produtor 2) para obter dados que vão ser acoplados ao e-mail. Podemos acessar essa

aplicação Web também mediada pelo ESB. Nesse caso, ganhamos também a capacidade

do Consumidor 2 de acessar a informação do Produtor 1, uma vez que ele já está

conectado ao ESB.

Matematicamente, temos que o número de conexões com o ESB cresce em

progressão linear (cada aplicação precisa se comunicar com o ESB), enquanto as

Page 40: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

27

interconexões entre os múltiplos sistemas crescem em progressão exponencial. Desta

forma, o uso de ESBs se torna vantajoso principalmente para diminuir a complexidade

do sistema como um todo.

3.2.1 – JBoss Fuse

JBoss Fuse é uma plataforma open-source desenvolvida para o JBoss Developer

Studio baseada na plataforma Apache ServiceMix, que agrega tecnologias como o

Apache ActiveMQ e Apache Karaf. O Fuse foi a plataforma ESB utilizada na plataforma

SotreqLink [20].

Além de sua capacidade integradora, a plataforma Fuse nos permite realizar

agendamento de tarefas. Podemos decidir em que momento determinada tarefa deverá ser

executada e com que frequência. Este agendamento foi utilizado na plataforma

SotreqLink como um todo, além deste projeto específico.

3.3 – Linguagem Scala

O nome Scala é um acrônimo para “Scalable Language”, que significa

“Linguagem Escalável” em tradução livre. O desenvolvimento da linguagem começou

em 2001, se tornando pública somente em 2004. A discussão aqui se baseia em sua

própria documentação presente em [21] e foca no que tange o interesse deste projeto.

O código fonte de Scala é compilado para o Java Bytecode sendo, portanto,

executado na máquina virtual Java. Além disso, bibliotecas Java e Scala podem ser

utilizadas em ambas as linguagens indiscriminadamente, caracterizando a

interoperabilidade das linguagens. Como Java é uma das linguagens mais populares do

mundo [22], existem diversas bibliotecas desenvolvidas e maduras. A interoperabilidade

faz com que Scala, apesar de ser uma linguagem bem mais recente que Java, possa

usufruir dessas ferramentas, o que caracteriza uma grande vantagem.

Sobre os paradigmas de programação, Scala é considerada como multiparadigma.

Como Java, Scala suporta os paradigmas de Orientação a Objetos, Imperativa e

Concorrente. Entretanto, Scala também tem suporte à programação funcional, absorvendo

Page 41: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

28

as qualidades discutidas na sessão anterior, o que Java não possui5. Por se tratar de uma

linguagem flexível, pois mescla vários estilos de programação, Scala é uma opção popular

para implementar o modelo de Fork-Join, facilitando para o desenvolvedor a alternância

entre os estilos imperativos, para a fração sequencial do programa, e funcional, para a

fração paralela do programa. Finalmente, Scala apresenta uma sintaxe mais concisa e

inteligível que Java, por exemplo, agilizando o desenvolvimento como um todo.

Por todas as vantagens descritas acima, Scala se torna uma opção atraente para

este projeto. Adicionalmente, a linguagem também conta com o suporte dos drivers do

Cassandra e da API do Apache Spark, framework de processamento para Big Data que é

descrito adiante.

3.4 – Apache Spark

O Apache Spark pode ser definido como um mecanismo rápido e genérico para

processamento de dados em larga escala. A plataforma ocupa uma posição de destaque

neste projeto, visto que é o motor de processamento que implementa o paralelismo e a

distribuição comentados nos capítulos anteriores. A maior parte da discussão a seguir foi

baseada no próprio site da plataforma [23].

3.4.1 – Arquitetura

Spark pode ser utilizado tanto localmente (em apenas uma máquina) quanto em

um cluster de computadores. A operação local implementa o paralelismo entre os

processadores (ou núcleos) de um computador apenas. Enquanto é valido para aplicações

não distribuídas, este modo de operação foge ao objetivo deste trabalho de implementar

uma solução distribuída. Portanto, será descrito aqui o modo de operação do Spark em

um cluster, chamado de cluster mode (Fig. 3.1).

5 Java 8 apresenta suporte a funções anônimas e notação lambda, sendo um avanço na direção de

programação funcional da linguagem.

Page 42: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

29

Fig. 3.1 Arquitetura do Spark em modo cluster [24]

A arquitetura de um cluster Spark apresenta três elementos principais: Cluster

Manager, Driver Program e Worker Node. O Cluster Manager é um serviço externo

responsável por gerenciar, coordenar e distribuir as tarefas da aplicação em questão.

Adicionalmente, é ele que realoca as tarefas e redistribui os recursos em caso de falha de

um dos nós do cluster. Em caso de falha do driver, por exemplo, um nó worker é

substituído para executar o driver. O nó em que se encontra o cluster manager é

comumente chamado de Mestre. É importante notar, no entanto, que o nó mestre pode

ser fisicamente o mesmo em que se encontra o driver, um worker ou até mesmo estar em

uma máquina dedicada.

O Driver Program é o processo principal executado em uma aplicação Spark,

normalmente executando a função Main() da aplicação. É neste nó que se executa o fluxo

principal do programa, responsável pelas operações não distribuídas do cluster. Ele ainda

é responsável por instanciar o SparkContext, que coordena os diversos conjuntos de

processos de um cluster. É através do SparkContext que a API do Spark é exposta e

permite ao desenvolvedor realizar a distribuição de trabalho quando e como desejar.

Exemplos do uso da API e do SparkContext serão vistos adiante.

Finalmente, o Worker Node são os nós que podem executar código da aplicação.

Para tal, eles utilizam executores, que processam as tarefas requisitadas e mantêm dados

Page 43: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

30

em memória ou os armazenam em disco. Um nó worker pode ter uma ou mais instâncias

de executores. Os Workers devem executar as tarefas sempre que possível,

principalmente as mais custosas, evitando assim a ociosidade de recursos, sobrecarga do

nó driver e ainda diminuir o tempo de execução.

3.4.2 – Programação

Como foi dito anteriormente, uma aplicação Spark consiste principalmente em um

Driver Program, que executa a função principal do programa e realiza as operações

paralelas em um cluster. Para realizar o paralelismo, o Spark dos disponibiliza uma

abstração chamada de RDD (Resilient Distributed Dataset). RDD é uma coleção de dados

particionada através dos nós do cluster e pode ser operada em paralelo. Adicionalmente,

RDDs são tolerantes a falhas, significando que, se um nó do cluster falhar sobre uma

operação em RDD, a aplicação consegue se recuperar e executar a tarefa requisitada

posteriormente. RDD é a principal forma de implementação de paralelismo que Spark

oferece. Um RDD pode ser criado invocando o método de paralelização diretamente do

SparkContext sobre uma coleção, ou ainda referenciado um conjunto de dados

distribuído.

Uma outra abstração que Spark oferece é o de variáveis compartilhadas. Por

padrão, Spark envia uma cópia de cada variável que será utilizada na função executada

em paralelo. No entanto, em alguns casos é necessário que que uma variável seja

compartilhada entre tarefas ou entre os nós de um cluster. Existem dois tipos de variáveis

compartilhadas no Spark: Variáveis Broadcast e Acumuladores. Enquanto

acumuladores foram discutidos na sessão sobre programação funcional, uma variável

broadcast é usada para armazenar um valor na memória de todos os nós do cluster. É

muito útil para minimizar o reenvio e a redistribuição de informação entre os nós do

cluster (o que é conhecido como Shuffle), garantindo que a informação já esteja

disponível na memória local de cada nó antecipadamente, aumentando a performance.

O desenvolvimento de uma aplicação Spark é feito em torno das abstrações

descritas acima, principalmente sobre RDDs. Existem dois tipos de operações suportadas

sobre RDDs: Transformações e Ações. Transformações são operações que retornam

uma nova coleção a partir de uma outra coleção. Como exemplo, as operações Map e

Page 44: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

31

Filter discutidas anteriormente são transformações no contexto do Spark.

Consequentemente, transformações sobre RDDs retornam novos RDDs. A Tabela 3.3

apresenta alguns exemplos de Transformações.

Transformação Descrição

map(func) Retorna um novo RDD formado pelo retorno de func em cada

elemento.

filter(func) Retorna um novo RDD formado pelos elementos em que func

retornou verdadeiro.

flatMap(func) Similar a map, porém func pode retornar 0 ou mais elementos.

O RDD retornado será a concatenação de todos os elementos.

groupByKey() Quando chamado sobre um RDD do tipo chave-valor, retorna

um RDD do tipo chave-coleção.

reduceByKey(func)

Quando chamado sobre um RDD do tipo chave-valor, retorna

outro RDD do tipo chave-valor onde o valor é o resultado da

agregação dos valores de mesma chave por func

Tabela 3.3 Exemplos de Transformações. Adaptado de [25]

Por outro lado, Ações são operações que retornam um valor para o programa

driver após realizado o processamento em um conjunto de dados. A operação Reduce

descrita anteriormente é um claro exemplo. Ela agrega todos os elementos de um RDD

utilizando a função passada como argumento e retorna o resultado para o driver. Segue a

Tabela 3.4 com alguns exemplos de ações.

Ação Descrição

reduce(func) Agrega os elementos do RDD utilizando func e retorna o valor para

o driver.

collect() Retorna todos os valores de um RDD para o driver na forma de um

Array.

count() Retorna o número de elementos de um RDD para o driver.

take(n) Retorna os primeiros n elementos do RDD para o driver.

Tabela 3.4 Exemplos de Ações. Adaptado de [25]

Page 45: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

32

As operações de transformação no Spark são do tipo Lazy. Operações lazy não

são executadas imediatamente. Em vez disto, transformações em RDDs retornam

ponteiros para outros RDDs. As transformações são efetivamente avaliadas apenas

quando se precisa do resultado. Isto ocorre quando uma ação precisa do resultado para

ser enviado para o driver. O uso de operações lazy permite que o Spark possa otimizar as

transformações dependendo do resultado exigido, ganhando performance no processo.

Adicionalmente, o Spark oferece suporte à persistência. O desenvolvedor pode

escolher persistir um RDD em memória ou disco, conforme achar conveniente. Por

exemplo, se mais de uma ação precisa de um estado intermediário de um mesmo RDD, é

conveniente que o mesmo seja persistido em memória para evitar que a mesma

transformação seja executada mais de uma vez. O método cache, por exemplo, realiza a

persistência em memória de um RDD.

Para ilustrar o uso de uma aplicação Spark, a Fig. 3.2 ilustra um código escrito em

Scala.

1

2

3

4

5

6

7

8

9

10

11

12

13

def GetMostUsedIp() : (String, Int) = {

val lines : RDD[String] = sparkContext.textFile("Log_Ip.csv") val ips : RDD[String] = lines.map(x => x.split(",").head) val ipsInt : RDD[(String, Int)] = ips.map(x => (x,1)) val ipsQuantity : RDD[(String, Int)] = ipsInt.reduceByKey((acc, x) => acc + x) val mostUsedIp : (String, Int) = ipsQuantity.reduce((acc, x) => { if(acc._2 >= x._2) return acc return x }) mostUsedIp

}

Fig. 3.2 Exemplo de aplicação Spark: Contagem de IP

O objetivo da função GetMostUsedIp() é extrair o endereço de IP que mais acessa

uma aplicação web. O servidor da aplicação conta com um arquivo de log do tipo CSV

cujo nome é “Log_Ip.csv”, onde cada linha do arquivo representa um registro e cada

Page 46: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

33

elemento do registro é separado por virgulas. Cada registro no nosso arquivo de log é

composto pelo IP no usuário e pelo momento de acesso, nesta ordem.

O primeiro comando executado pela função é o método textFile invocado através

da instância de SparkContext. Passando o nome do arquivo como argumento, textFile

distribui o arquivo entre os workers do cluster, sendo cada linha do arquivo um elemento

do RDD, formando assim um RDD de String. Como estamos interessados apenas no

número de acessos, a linha 4 do código acima separa a linha do arquivo CSV pela vírgula

e extrai apenas o primeiro elemento (head), descartando a hora de acesso. Posteriormente

é realizado um novo mapeamento na linha 5, desta vez colocando o IP como chave e o

número 1 como valor de nossa tupla. Isto será útil para a operação seguinte, o

reduceByKey. Quando invocado, reduceByKey irá retorna um RDD do tipo chave-valor,

onde a chave será o IP em questão e o valor a quantidade de vezes que o IP foi registrado

em nosso log. Finalmente, a função do argumento de Reduce na linha 7 retorna para o

acumulador apenas a tupla em que o IP apresentar o maior número de acessos. Assim,

temos que, ao final de sua execução, a função GetMostUsedIp() irá retornar uma tupla

contendo o IP com o maior número de acessos e sua quantidade de acessos.

3.5 – Telemetria dos equipamentos

Para realizarmos a manutenção preditiva dos equipamentos, objetivo principal

deste projeto, são necessárias informações sobre os mesmos. Os equipamentos Sotreq,

majoritariamente de fabricação Caterpillar, contam com um avançado sistema de

hardware que realiza o monitoramento das máquinas. Estas informações são

fundamentais para a realização da manutenção preditiva.

3.5.1 – Servidor VisionLink

O servidor VisionLink é um webservice para o qual as máquinas Sotreq enviam

mensagens sobre o seu estado interno. Entre essas mensagens, temos informações sobre

a utilização de combustível, horários de operações e falhas e/ou diagnósticos ocorridos.

Este sistema está conectado com módulos ProductLink: módulos de hardware

integrados aos equipamentos da Sotreq que coletam informações dos componentes dessa

Page 47: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

34

máquina e enviam informações para um servidor central da plataforma VisionLink

através de conexão via satélite [26]. Entretanto, esta conexão pode ser interrompida,

ocasionando em um atraso na entrega da falha ao servidor. Esta característica deve ser

considerada no desenvolvimento da aplicação.

Este servidor é subdividido em URLs, uma para cada tipo de mensagem

(combustível, falhas, estado atual, etc.). Essas mensagens são representadas em XML em

uma fila, onde são enfileiradas em ordem decrescente de recebimento.

Para manter o escopo deste documento, será descrito o formato e o teor das

mensagens relativas à saúde do equipamento. Estas mensagens enviam 5 tipos de

informações diferentes que em conjunto informam ao técnico competente o exato

problema que que o equipamento pode possuir. Segue a lista com os tipos de informações:

Evento/Diagnóstico: Diz se a informação é referente a um evento ou diagnóstico

MID: Código numérico que identifica o módulo de controle eletrônico que

detectou a falha

CID: Código numérico que identifica o componente envolvido na falha

FMI: Código numérico que informa o tipo de falha ocorrido

Timestamp: Momento em que a falha ocorreu

Page 48: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

35

Capítulo 4

Desenvolvimento da Aplicação

Neste capítulo, é descrita a implementação da proposta deste trabalho utilizando

as tecnologias discutidas no capítulo anterior. Primeiramente, detalharemos as empresas

envolvidas neste projeto, mencionando suas áreas de atuação e contribuição para este

trabalho.

Na segunda seção, é descrita a arquitetura proposta para o nosso sistema, exibindo

o fluxo de informação desde a interface com o operador até o processamento das

informações de falhas dos equipamentos, e retornando para o usuário apenas a informação

útil, que é a detecção dos padrões de falhas.

Em seguida, detalhamos a primeira parte do fluxo de dados, começando com os

padrões de falhas que se deseja extrair, até chegarem ao cluster.

Posteriormente, serão descritas as estratégias de processamento distribuído

realizadas pelo Spark e sua integração com o Cassandra. É visto também como as

informações a respeito do equipamento foram salvas no banco e seu impacto.

4.1 – Empresas

Duas empresas participaram da realização deste trabalho. A primeira é a Radix

Engenharia e Software, prestadora do desenvolvimento da plataforma SotreqLink. A

segunda é a Sotreq, o cliente deste projeto.

4.1.1 – Radix Engenharia e Software

A Radix Engenharia e Software foi fundada em abril de 2010 pelos antigos sócios

da Chemtech. Ainda no seu primeiro ano de funcionamento, a empresa superou a marca

de 100 funcionários. Há cinco anos ocupa um lugar de destaque na Lista das Melhores

Empresas para se Trabalhar, prêmio este concedido pela Great Place to Work Institute em

Page 49: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

36

parceria com grandes veículos de comunicação do país. Sediada no Rio de Janeiro, a

empresa também possui escritórios em Volta Redonda (RJ), Belo Horizonte (MG), São

José dos Campos (SP), São Paulo (SP) e Houston (EUA) [27].

A Radix conta como clientes empresas como: AkerSolutions, Braskem, CSN,

Deten, FosBrasil, GDK, iMusica, Keppel Fels, Laborvida, Monsanto, Nitriflex,

Petrobras, Supervia, TV Globo, Vale.

Atualmente, a Radix conta com diversos projetos de engenharia e software nas

áreas de petróleo e gás, metais e mineração, agronegócio entre outras.

4.1.2 – Sotreq

O grupo Sotreq é o revendedor oficial de peças, máquinas, serviços e sistemas da

Caterpillar no Brasil. Fundada em 1941 com um contrato firmado com a Caterpillar,

passou as décadas seguintes expandindo seu negócio por todo o Brasil. Atualmente possui

mais de 40 filiais e é uma das maiores revendedoras Caterpillar do mundo [28].

A Sotreq é uma empresa de capital 100% nacional, cujo diferencial é o suporte

aos produtos vendidos, contando com diversas unidades de apoio a reposição de peças,

sistemas de monitoramento e serviços mecânicos. A Sotreq fornece equipamentos nas

áreas de construção civil, mineração, petróleo e gás.

Visando a modernizar sua área de software e agregar valor aos serviços prestados,

em 2015 o Grupo Sotreq adquiriu 50% da Radix. Com essa aquisição, foi criada a

Unidade de Negócio de Metais, Mineração e Agronegócio na Radix, onde este projeto foi

desenvolvido.

4.2 – Arquitetura

A plataforma SotreqLink, na qual este projeto está inserido, é composta por

diversos módulos e serviços, que se comunicam e complementam. É dentro desta

estrutura já estabelecida que este projeto deve ser inserido. São expostos aqui apenas os

componentes relevantes da arquitetura para este projeto, sendo abstraídos outros serviços

e servidores da rede. A arquitetura proposta é detalhada na Fig. 4.1.

Page 50: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

37

Fig. 4.1 Arquitetura Geral do Sistema

As setas da figura representam o sentido do fluxo de dados. De acordo com a

arquitetura atual, o operador do sistema acessa através de um único servidor, que foi

batizado com o nome do projeto. O servidor SotreqLink é o responsável por abrigar o

website que realiza a interface com o usuário. É nele também que são implementadas as

diversas regras de negócio do sistema, incluindo a geração de padrões de falhas dos

equipamentos, além de salvar diversas outras informações no banco de dados. O website

ainda exibe todos os dados e/ou resultados importantes para o usuário, o que explica o

fluxo bidirecional de informação entre o servidor e o usuário.

O servidor SotreqLink, por sua vez, estabelece comunicação apenas com o banco

de dados Oracle (além do operador). Como foi discutido no Capítulo 2, o Oracle é

classificado como um SGBD Relacional, apresentando, portanto, as vantagens que este

tipo de ferramenta possui. Como o servidor SotreqLink apresenta para o usuário apenas

as informações relevantes, ele não apresenta um volume de dados muito grande, se

comparado ao Cassandra, por exemplo. É neste banco também que se encontra o cadastro

dos equipamentos cobertos pela manutenção preditiva. Isto faz com que a escolha por um

banco relacional consiga atender perfeitamente à demanda da aplicação, além de evitar

replicação de dados e oferecer diversas ferramentas úteis à busca que não existem em

bancos não relacionais.

Page 51: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

38

No centro da imagem encontra-se o JBoss Fuse, que é a solução ESB integrada

ao projeto. Apresentado no capítulo anterior, ESBs tem o objetivo de facilitar a integração

entre os diversos sistemas, evitando a complexidade de realizar essas integrações de

forma independente. Por estar conectado aos diversos servidores, o JBoss é responsável

por executar rotinas agendadas, principalmente no que diz respeito ao remanejamento de

dados entre os servidores. Por este motivo, o JBoss Fuse ocupa um lugar central em nossa

arquitetura, atuando com um grande hub.

O webservice Visionlink, responsável por enviar os dados de telemetria dos

equipamentos, é o único da arquitetura que apenas envia dados ao JBoss. Apesar do

servidor JBoss realizar as requisições ao VisionLink, nenhum dado útil é enviado, o que

justifica uma única seta da direção do JBoss.

Finalmente, temos o cluster Spark/Cassandra à direita da figura, se comunicando

com o JBoss. A escolha de posicionar o cluster se comunicando com o JBoss vai ao

encontro da arquitetura da plataforma como um todo. Além de manter o padrão do

projeto, permite que outros serviços também usufruam do poder de

processamento/armazenamento que o cluster pode proporcionar. Poderíamos ter

posicionado o cluster se comunicando com o servidor SotreqLink por exemplo, mas,

apesar de facilitar a aplicação deste projeto, resultaria em uma dificuldade muito maior

para que outros módulos pudessem acessar o cluster.

4.2.1 – Configuração do cluster

Para este projeto foram disponibilizados pela Radix 3 computadores para compor

o cluster. Cada um deles conta com 2GB de memória RAM e 6 núcleos de processamento.

Todas as máquinas executam instâncias Spark, sendo uma delas o nó driver e os outros 2

os workers, conforme visto na sessão sobre arquitetura do Spark.

Sobre o banco de dados Cassandra, foi decidido que ele ficaria distribuído por

duas dessas máquinas, preferencialmente os nós executores. Desta forma, os nós

executores terão acesso direto aos dados em forma já distribuída, não tendo a necessidade

de realizar uma operação de paralelização e minimizando o Shuffle. Por não realizar o

Page 52: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

39

processamento sobre o conjunto RDD, o nó driver não precisa de acesso direto ao

Cassandra.

Outro aspecto importante na configuração do cluster é o fator de replicação dos

dados do Cassandra. A replicação ajuda a garantir a disponibilidade do sistema, assim

como facilita a própria distribuição da carga de trabalho. Foi escolhido um fator de

replicação 2, ou seja, todas as máquinas Cassandra terão acesso a todos os dados

simultaneamente. A estratégia de replicação poderá ser alterada no futuro, caso se mostre

inviável manter todos os nós Cassandra com todas as informações. Em um cenário de

crescimento do cluster e/ou aumento do volume de informação, será conveniente alterar

o fator de replicação.

4.3 – Fontes de Informação

Nesta seção é descrito como são obtidas as informações necessárias para o

reconhecimento de um padrão de falha. Naturalmente, precisamos das próprias falhas dos

equipamentos e do fornecimento de um padrão para ser encontrado.

4.3.1 – Falhas

Como foi discutido no capítulo anterior, as falhas dos equipamentos são

detectadas automaticamente por meio de sensoriamento eletrônico. A comunicação com

o webservice VisionLink é realizada via satélite, permitindo que a comunicação seja

estabelecida inclusive em regiões com difícil acesso à internet. Mesmo assim, alguns

equipamentos apresentam atraso ao reportar a sua saúde, o que deve ser levado em

consideração no desenvolvimento da aplicação.

Considerando que as falhas podem chegar a qualquer momento no VisionLink,

uma rotina no JBoss monitora constantemente o webservice para, tão logo uma falha

esteja disponível, ela ser recolhida e enviada para o nó driver do Spark, que por sua vez

irá paralelizar a informação entre os executores do cluster para serem salvas no Cassandra

em formato adequado.

Page 53: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

40

4.3.2 – Padrões

De acordo com a proposta deste projeto, a manutenção preditiva é realizada

através da análise das falhas reportadas pelos equipamentos em campo. Para tal, o técnico

competente deve informar ao sistema o padrão de falhas que deseja ser encontrado no

histórico de falhas do equipamento.

A inclusão destes padrões é feita pela interface web do servidor SotreqLink. A

partir das condições que o usuário inserir no sistema, automaticamente é gerada uma

Regra, que é uma expressão que sintetiza o padrão de erro a ser reconhecido. A seguir,

detalha-se o conceito de regra.

4.3.2.1 – Regras

De maneira geral, regra é a tradução das condições impostas pelo operador do

sistema em uma expressão lógica que deverá ser utilizada como fonte na interpretação

das falhas ocorridas. Quando uma regra identifica um padrão de falha, dizemos que foi

gerada uma violação.

Cada regra possui como alvo um modelo de equipamentos. Desta forma, a mesma

regra se aplica a todos os equipamentos que possuem em seu cadastro o modelo alvo da

regra. É importante ressaltar que mais de uma regra pode ter como alvo o mesmo modelo.

A expressão de uma regra é composta por três tipos de informação: Tags,

Operadores e Argumentos. Uma tag é a representação dos códigos de uma falha. A tag

é especificada pelo operador ao fornecer um evento ou diagnóstico, e os códigos MID,

CID e FMI. Foi convencionado que a tag seria precedida pelo símbolo “#” para ser

facilmente identificada pelo interpretador. A seguir temos um exemplo de tag evento,

com códigos MID = 123, CID = 456 e FMI = 789:

#1.123.456.789 (4.1)

Page 54: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

41

Os operadores por sua vez representam as restrições lógicas do padrão

informados pelo técnico competente. Eles podem vir acompanhados, ou não, de um

argumento. Vejamos a seguinte regra exemplo com o operador “OU”:

#1.123.456.789 OU #2.234.345.456 (4.2)

Neste caso, o operador está expressando que deseja ser comunicado quando

quaisquer das duas tags acima forem reportados pelo equipamento. Vejamos agora um

exemplo com o operador “E”:

#1.123.456.789 E:60 #2.234.345.456 (4.3)

Na regra acima, o operador expressa que deseja ser notificado se ambas as tags

forem registradas em um intervalo de 60 segundos. Portanto, o operador “E” é

acompanhado de um argumento, que representa o tempo, em segundos, da janela de filtro

que será aplicado.

Por último, temos o operador “tti”, que significa tempo para ignorar. Este

operador é sempre aplicado por último, já sobre as violações da regra. Ele informa para o

interpretador o tempo mínimo que deve se passar para uma nova violação ser considerada.

Vejamos um exemplo com o uso de “tti”:

#1.123.456.789 tti:120 (4.4)

Agora, suponhamos que o equipamento alvo apresentou a tag em questão nos

momentos 𝑡0 = 0𝑠, 𝑡1 = 100𝑠 , 𝑡2 = 150𝑠 e 𝑡3 = 200𝑠. Teríamos como resultado

apenas as violações ocorridas em 𝑡0 e 𝑡2, pois o intervalo entre 𝑡0 e 𝑡1 é inferior ao

argumento de “tti”, assim como o intervalo entre 𝑡2 e 𝑡3.

Regras também têm suporte a múltiplos operadores, assim com o uso de

parênteses para se definir a prioridade das operações. Vejamos a seguir uma regra mais

complexa, utilizando-se de todos os operadores apresentados (as tags foram substituídas

por letras para facilitar o entendimento).

Page 55: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

42

( #A E:20 #B ) OU ( #C E:30 #D ) tti:40 (4.5)

Para facilitar o entendimento da aplicação das condições, iremos demonstrar

como a regra acima deve ser interpretada de acordo com as falhas reportadas pelo

equipamento. Na Fig. 4.2, temos um caso hipotético, onde é demonstrada a execução de

cada passo da regra. Acima de cada seta, está representado o tempo, enquanto abaixo

estão representadas as falhas ou violações.

Fig. 4.2 Aplicação da Regra

A primeira condição aplicada gera duas violações (em vermelho), representadas

por #V1 e #V2. Foi convencionado que a violação ocorreria no momento da última tag

envolvida na condição. No caso de #V1, como a tag #A antecede a tag #B, a violação

#V1 ocorre no mesmo momento que a tag #B. O mesmo ocorre na aplicação da segunda

condição (em azul), onde a violação #V3 ocorre no mesmo momento de #D. O operador

OU, por sua vez, concatena os resultados das duas condições acima, retornando as

violações #V1, #V2 e #V3. O último filtro, “tti:40”, irá desconsiderar qualquer violação

cuja diferença de tempo entre ela e a anterior seja menor que o tempo indicado. Como

Page 56: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

43

#V3 ocorre cerca de 20 segundos após #V1, #V3 deve ser descartada. Assim, a

interpretação da regra com as tags fornecidas acima deve retornar apenas as violações

#V1 e #V2.

4.4 – Estrutura dos Bancos de Dados

Nesta sessão são descritas as organizações das informações nos bancos de dados

utilizados neste projeto. Como foi visto na arquitetura geral, temos dois diferentes bancos:

Oracle e Cassandra. Ainda como foi dito anteriormente, a informação significativa para

o usuário deverá ser armazenada no banco Oracle, enquanto os dados não processados

serão convenientemente armazenados no banco Cassandra.

4.4.1 – Oracle

Existem dois tipos de informação que serão armazenados no banco Oracle com o

objetivo de serem facilmente obtidas e manipuladas pelo operador do sistema. As Regras,

que serão adicionadas pelo operador conforme a necessidade, e as Violações, que serão

adicionadas após o processamento das falhas realizados no cluster.

Com foi visto na sessão anterior, uma regra é formada pela sua expressão lógica

e pelo seu alvo, que define em que equipamentos as regras serão aplicadas. O alvo é um

código que define um modelo de equipamento e, portanto, todos os equipamentos que

pertencem ao modelo são alvos da regra.

Para armazenar a regra, foi criada uma tabela com o nome PR_REGRA, onde o

prefixo PR indica apenas que a tabela está relacionada ao módulo de manutenção

preditiva. Esta tabela conta com três colunas, ID_REGRA, DE_MODELO e

DE_EXPRESSAO. A coluna ID_REGRA é a chave primária da tabela e um identificador

único do registro. DE_MODELO armazena o nome do modelo dos equipamentos que

serão os alvos das regras. Finalmente, DE_EXPRESSAO armazena as condições lógicas

da regra que serão aplicadas sobre as falhas. Segue um exemplo na Tabela 4.1 (as tags

foram substituídas por letras para facilitar o entendimento):

Page 57: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

44

PR_REGRAS

ID_REGRA DE_MODELO DE_EXPRESSAO

1 JAP #A OU #B

2 JAP (#C E:30 #D) OU (#E E:10 #C)

3 HWM #A E:40 #B

4 FAO #B OU #C

5 MNS #A OU #B OU #C

Tabela 4.1 Regras

O banco Oracle também será responsável por armazenar as violações. A violação

deve armazenar o momento da violação e o número de série do equipamento envolvido.

Também é importante indicarmos a regra que deu origem a violação, através do uso de

chave estrangeira.

Desta forma, foi criada a tabela PR_VIOLACOES, com as seguintes colunas:

ID_VIOLACAO, ID_REGRA, DE_SERIAL_NUMBER e DT_TIMESTAMP. A coluna

ID_VIOLACAO é a chave primária da tabela e identificador único do registro.

ID_REGRA é a chave estrangeira para a tabela PR_REGRAS e indica a regra que deu

origem a violação. DE_SERIAL_NUMBER representa o número de série do

equipamento e DT_TIMESTAMP o momento que a violação ocorreu. Um exemplo de

PR_VIOLACOES pode ser visto na Tabela 4.2.

PR_VIOLACOES

ID_VIOLACAO ID_REGRA DE_SERIAL_NUMBER DT_TIMESTAMP

1 2 HFW019345 17/11/2016 14:17

2 2 HFW019345 17/11/2016 14:19

3 6 JAP001245 18/11/2016 11:39

4 7 FAO099344 19/11/2016 18:20

5 10 FLW010345 21/11/2016 10:11

Tabela 4.2 Violações

Foi visto na sessão sobre tecnologias utilizadas que este projeto utilizou o ORM

Entity Framework da Microsoft em linguagem C#. Veremos em seguida como ficou o

Page 58: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

45

mapeamento destas classes na aplicação do servidor SotreqLink. Primeiramente, veremos

a tabela PR_REGRAS, ilustrada pela Fig. 4.3.

[Table("PR_REGRAS")] public class Regras : BaseRegister { [Column("ID_REGRA")] public override int Id { get; set; } [Column("DE_MODELO")] public string Modelo { get; set; } [Column("DE_EXPRESSAO")] public string Expressao { get; set; } public virtual ICollection<Violacoes> Violacoes { get; set; } }

Fig. 4.3 Mapeamento de PR_REGRAS

Podemos observar que, além das colunas terem sido mapeadas conforme a tabela,

existe a inclusão de uma coleção Violacoes. Esta coleção é formada pelos registros da

tabela PR_VIOLACOES que apontam, através da chave estrangeira, para a tabela

PR_REGRAS. Desta forma, um objeto de Regras possui uma coleção de violações que

apontam para o seu Id. Vejamos a seguir o mapeamento de PR_VIOLACOES (Fig. 4.4).

Page 59: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

46

[Table("PR_VIOLACOES")] public class Violacoes : BaseRegister { [Column("ID_VIOLACAO")] public override int Id { get; set; } [Column("ID_REGRA")] public int IdRegra { get; set; } [ForeignKey("IdRegra")] public virtual Regra Regra { get; set; } [Column("DE_SERIAL_NUMBER")] public string SerialNumber { get; set; } [Column("DT_TIMESTAMP")] public DateTime Timestamp { get; set; } }

Fig. 4.4 Mapeamento de PR_VIOLACOES

Assim como ocorreu no caso anterior, temos as propriedades mapeadas de acordo

com as colunas que representam. Além disso, temos a indicação de que a propriedade

IdRegra é uma chave estrangeira que aponta para o objeto Regra. Desta forma, um objeto

da classe Violacoes ganha acesso ao objeto Regra apontado por ele.

4.4.2 – Cassandra

O banco de dados Cassandra é responsável por armazenar os dados de falhas dos

equipamentos, que serão processados para serem obtidas as violações das regras

correspondentes. Para atingir tal objetivo, iremos utilizar duas tabelas: PR_FALHAS e

PR_FALHAS_TEMP.

A tabela PR_FALHAS será constituída por seis colunas: BUCKET, TAG,

MODEL, TIMESTAMP, SERIAL_NUMBER e INSERT_TIME. A coluna BUCKET é

a primeira chave primária e irá conter um inteiro que representa o dia em que a violação

foi recebida. Esta estratégia nos permite realizar uma busca por todas as falhas que

aconteceram no mesmo dia, indo ao encontro da proposta de realizar o processamento

das falhas uma vez ao dia. A coluna TAG irá conter o código de falha, enquanto as colunas

MODEL, SERIAL_NUMBER e TIMESTAMP armazenarão, respectivamente, o modelo

Page 60: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

47

do equipamento, o número de série do equipamento e o momento da falha. Finalmente, a

coluna INSERT_TIME é a única coluna que não faz parte da chave e irá conter o

momento em que o dado foi inserido no banco de dados. A Tabela 4.3 é um exemplo.

PR_FALHAS

Chave Valor

BUCKET TAG MODEL SERIAL_NUMBER TIMESTAMP INSERT_TIME

20161118 #A JAP JAP00100 16/11/2016 13:34 18/11/2016

20:30

20161118 #A JAP JAP00100 16/11/2016 17:49 18/11/2016

20:30

20161118 #B HWV HWV00241 16/11/2016 11:10 18/11/2016

20:30

20161119 #C HWV HWV00257 18/11/2016 18:44 19/11/2016

20:30

20161119 #C FLW FLW00123 18/11/2016 18:47 19/11/2016

20:30

Tabela 4.3 Falhas dos Equipamentos

A tabela PR_FALHAS_TEMP, por sua vez, terá a função de armazenar as falhas

que não se converteram em violações e ocorreram ainda após a última violação registrada.

Isto é necessário pois, como foi visto na descrição do webservice VisionLink, as falhas

podem chegar com atraso no sistema. Por isso, uma falha que não gerou uma violação em

um determinado dia, poderá gerar caso uma outra falha necessária chegue ao sistema

posteriormente. Foi acordado com o cliente que sete dias é o período máximo que uma

regra deve permanecer na tabela temporária. A tabela temporária deverá conter uma

coluna a mais, a ID_REGRA, que contém o identificador da regra em que a falha não se

converteu em uma violação. O identificador da regra é importante para distinguir as falhas

que foram convertidas em violações em uma regra, mas não foram em outra. Neste caso,

é interessante que apenas as regras correspondentes possam reavaliar estas falhas

posteriormente. A coluna BUCKET foi alterada para receber apenas um inteiro. O

objetivo do bucket agora é auxiliar na escrita e limpeza da tabela. Como a tabela será

reescrita a cada processamento, é conveniente que primeiro sejam salvos os novos dados

temporários para depois remover os antigos. Assim, a cada operação de reescrita, basta

alterar o bucket no momento da escrita e posteriormente apagar os dados com o bucket

anterior. Um exemplo pode ser visto na Tabela 4.4.

Page 61: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

48

PR_FALHAS_TEMP

Chave Valor

BUCKET TAG MODEL SERIAL_NUMBER ID_REGRA TIMESTAMP INSERT_TIME

1 #A JAP JAP00100 10 16/11/2011

13:34

16/11/2011

20:30

1 #A JAP JAP00100 10 16/11/2011

17:49

16/11/2011

20:30

1 #B HWV HWV00241 21 16/11/2011

11:10

16/11/2011

20:30

1 #C HWV HWV00257 33 18/11/2011

18:44

18/11/2011

20:30

1 #C FLW FLW00123 48 18/11/2011

18:47

18/11/2011

20:30

Tabela 4.4 Falhas Temporárias

4.5 – Aplicação Spark

Uma vez que as estruturas dos bancos de dados foram descritas, podemos agora

discutir a aplicação Spark, que será responsável por organizar os dados das diferentes

fontes de informação descritas, e processá-las de maneira distribuída e paralela, conforme

o objetivo deste trabalho. A aplicação foi desenvolvida utilizando-se majoritariamente

dos conceitos de programação funcional, apresentados anteriormente.

O nó driver do cluster é o responsável por receber as regras armazenadas no banco

Oracle. As informações provenientes do Cassandra já se encontram distribuídas no cluster

devido à natureza do próprio banco de dados. Uma vez iniciado o processamento, o driver

invoca o método Processar, que recebe como argumentos a coleção de regras do Oracle,

enviadas pelo JBoss, e o bucket, que representa a data dos dados a serem processados.

Como o processamento ocorre uma vez ao dia, a data enviada é a do dia anterior. O código

do método principal, assim como métodos auxiliares e as classes que modelam os

elementos do banco, estão disponíveis no Apêndice A.

O principal objetivo do método Processar é organizar as diferentes informações

de maneira eficiente para que possam ser processadas de forma paralela e distribuída pela

aplicação. Dentro do contexto Spark, transformações sobre conjuntos deverão ser

Page 62: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

49

utilizadas para que o interpretador das regras possa operar de maneira eficiente, ou seja,

paralela e distribuída.

O método interpretador necessita de três argumentos, de acordo com o que foi

visto na sessão sobre regras: Falhas de um equipamento para uma dada regra, a expressão

lógica e o identificador da regra. O identificador serve apenas para associar a violação à

sua regra de origem. Estas três informações devem estar disponíveis de maneira

organizada para a interpretação ser realizada.

Temos, a princípio, três tipos de dados diferentes: falhas, falhas temporárias e

regras. Apenas as duas primeiras encontram-se distribuídas no cluster, enquanto as regras

encontram-se no driver da aplicação. O primeiro passo é determinar o bucket atual e o

próximo das falhas temporárias, que serão utilizados no fim deste processo. Em seguida,

é importante filtrarmos as falhas que não são alvos de nenhuma regra, assim como as

regras que não possuem nenhuma falha como alvo. A solução encontrada para isso foi

utilizar uma técnica chamada de broadcast join. Para facilitar o entendimento de todo o

fluxo, são demonstradas as transformações realizadas em um caso exemplo, começando

pela Fig. 4.5. Neste exemplo não estão sendo consideradas as falhas temporárias, por

simplicidade.

Fig. 4.5 Fluxo da Aplicação - Parte 1

A Fig. 4.5 nos mostra o início da aplicação. O objeto Regra é uma tripla contendo

o identificador da regra, o modelo do equipamento alvo e a expressão lógica da regra. O

objeto Falha é uma sêxtupla que contêm o bucket, a tag, o modelo, o número de série, o

momento da falha e o momento de inserção no banco Cassandra. Ambos os objetos foram

Page 63: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

50

definidos conforme as respectivas modelagens nos bancos de dados. A primeira operação

realizada é um FlatMap que retorna para cada Regra o conjunto das tags envolvidas em

sua expressão. O resultado é um conjunto chave-valor, onde a chave é a regra e o valor

uma da tags da expressão.

Fig. 4.6 Fluxo da Aplicação - Parte 2

A Fig. 4.6 exibe a segunda parte do fluxo. Primeiramente é realizada uma

operação de agrupamento por modelo do equipamento e tag, resultando em uma estrutura

do tipo dicionário. A chave é composta pelo modelo e tag, enquanto o valor do dicionário

é um conjunto de regras associadas a esta chave. Em seguida é realizada um broadcast

neste dicionário para que uma cópia desta estrutura fique disponível em cada nó do

cluster. Como o dicionário está disponível na memória local de cada worker, as falhas

podem acessá-lo de maneira eficiente e sem Shuffle de dados através de uma operação

Map que realiza essa consulta ao dicionário, como mostra a segunda linha da figura. Neste

caso, a consulta irá retorna um conjunto de regras que se relacionam com a falha em

questão. Caso a falha não encontre nenhuma regra correspondente no dicionário, o valor

“null” é retornado. Por fim, realizamos uma operação de filtro, retornando apenas as

falhas que tenham alguma regra associada e eliminado as falhas que retornaram “null” na

consulta ao dicionário. Este processo é chamado de broadcast join pois realizamos uma

operação equivalente ao comando join da linguagem SQL de bancos relacionais

utilizando uma variável broadcast do Spark.

Page 64: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

51

Fig. 4.7 Fluxo da Aplicação - Parte 3

A terceira parte do fluxo da aplicação é exemplificada na Fig. 4.7. Uma

transformação de FlatMap é necessária para planificar o conjunto de regras associadas a

cada falha. Assim, uma falha é replicada para cada regra associada em seu conjunto de

regras original. Desta forma a estrutura resultando é uma dupla onde os elementos são a

falha e a regra respectivamente. A operação seguinte é um Map simples, onde o objetivo

é criar uma estrutura chave-valor onde a chave é uma tripla contendo o número de série

do equipamento, o identificador da regra e a sua expressão lógica, enquanto o valor é a

falha do elemento original. Esta transformação é necessária para a operação de

agrupamento que será feita na próxima parte do fluxo, visto na Fig. 4.8.

Fig. 4.8 Fluxo da Aplicação - Parte 4

A Fig. 4.8 nos mostra a quarta e última parte do fluxo da aplicação. A primeira

transformação realizada é um agrupamento por chave. Como a chave da nossa estrutura

chave-valor é o número de série do equipamento, o identificador da regra e a expressão

da regra, temos que o resultado do agrupamento são todas as falhas de um mesmo

equipamento para uma dada regra. Assim, a estrutura resultante é exatamente os

argumentos necessários para serem passados para o método interpretar, que é feito através

de uma transformação FlatMap. Por fim, o resultado desta última operação são as

violações de cada equipamento para cada regra, cumprindo assim o objetivo da aplicação.

Page 65: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

52

Capítulo 5

Resultados

Desde a implementação deste projeto, o processamento de falhas e regras ocorre

uma vez ao dia, como especificado. Para verificar a quantidade média de violações que

foram geradas pela aplicação, foi executada uma query em nosso banco de dados

agrupando as violações por dia de ocorrência. A pesquisa nos retornou uma média de

aproximadamente 4210 violações por dia, como pode ser visto na Fig. 5.1.

Fig. 5.1 Média de Violações por dia

Além de atestar o funcionamento da solução, é interessante verificarmos o

comportamento da aplicação no que diz respeito ao paralelismo e distribuição. O Spark

possui uma interface de usuário web que nos fornece diversas métricas da aplicação. Para

cada ação executada, a interface nos fornece um DAG (Direct Acyclic Graph), que é uma

representação gráfica das transformações executadas em uma ação. O DAG da ação

collect(), que reúne as violações para o driver do cluster, pode ser visto na Fig. 5.2.

Page 66: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

53

Fig. 5.2 DAG da Aplicação

Podemos ver que o Spark dividiu a ação em dois estágios. No primeiro é realizado

o broadcast join e a união dos dois conjuntos de falhas. No segundo ocorre o agrupamento

por chave para então interpretar as regras. A cor verde na operação map do segundo

estágio indica que foi realizado um cache. Para cada estágio, a interface web nos fornece

ainda métricas específicas, como a linha do tempo das tarefas por executor. A Fig. 5.3

ilustra a linha do tempo do primeiro estágio.

Page 67: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

54

Fig. 5.3 Linha do Tempo Estágio 1

De acordo com a figura, o tempo total gasto do primeiro estágio é próximo de 6

segundos. Podemos observar que praticamente a totalidade do tempo foi usada com

processamento (em verde) em vez de outras atividades, como a serialização da tarefa. Ao

final de cada tarefa, uma pequena porção do tempo foi utilizado para Shuffle (em

amarelo). Isto é justificado pela primeira transformação do estágio seguinte, que é um

agrupamento por chave. Operações de agrupamento causam redistribuição dos dados no

cluster.

É importante notar ainda que cada executor consegue realizar, simultaneamente,

até 6 tarefas. Isto coincide com o número de núcleos especificados na configuração do

cluster. Finalmente, percebemos que o segundo executor realiza um trabalho

consideravelmente maior que o primeiro, cerca de 3 vezes mais. Isto pode ocorrer devido

as operações de filtro realizadas neste estágio. Filtros podem impactar cada nó de maneira

diferente, pois não é garantido que a mesma quantidade de dados seja filtrada em todos

os nós, deixando-os desbalanceados.

Podemos realizar análise semelhante no segundo estágio, conforme está ilustrado

na Fig. 5.4.

Page 68: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

55

Fig. 5.4 Linha do Tempo Estágio 2

A duração total deste estágio é de cerca de 100 milissegundos. Como no estágio

anterior, a maior parte do tempo foi usada com processamento. Além disso, cada executor

realiza 6 tarefas simultaneamente.

Podemos verificar, no entanto, duas diferenças em relação ao estágio anterior. A

primeira delas é a existência de tempo de leitura de shuffle (em laranja) em duas tarefas.

Isto é necessário para reunir as informações que foram distribuídas por escrita de shuffle

no estágio anterior. A segunda diferença é a existência de tempo de serialização de

resultado ao final de cada tarefa (em roxo). Por se tratar do último estágio, o resultado

final precisa ser enviado para o driver, o que ocorre por meio de serialização. Assim como

as tarefas passam por desserialização ao chegarem no executor, o resultado deve ser

serializado para ser enviado ao driver.

Page 69: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

56

Capítulo 6

Conclusões e Trabalhos Futuros

Para concluir este projeto, vamos analisar os resultados obtidos no capítulo

anterior. Podemos dizer que obtivemos sucesso, em primeiro lugar, por conseguirmos

identificar os padrões de erros gerados pelo técnico. Estes padrões, que chamamos de

violações, podem ser tratados de acordo com o interesse da empresa contratante.

Futuramente, estas violações terão tratamento automático do sistema, de acordo com a

regra de origem.

Também era objetivo deste trabalho realizar a identificação dos erros utilizando

tecnologias de Big Data, paralelismo e sistemas distribuídos. Como pode ser visto nas

Fig. 5.3 e Fig. 5.4, o processamento ocorreu de forma distribuída, envolvendo todos os

nós workers, e paralela, onde cada worker realizou até 6 tarefas simultaneamente. Um

ponto de atenção é o não balanceamento de dados evidenciado na Fig. 5.3. Uma sugestão

seria realizar uma redistribuição dos dados após a etapa de filtros, caso necessário.

Um outro objetivo deste projeto era conseguir uma arquitetura escalável conforme

a necessidade. Ao utilizarmos as ferramentas Spark e Cassandra, podemos adicionar mais

computadores ao cluster com o mínimo de esforço, bastando apenas registrar os novos

computadores ao cluster, não precisando alterar a aplicação. Finalmente, temos que o

tempo total do processamento ficou em torno de apenas 6 segundos, atendendo as

necessidades do cliente no momento.

O próximo passo é automatizar a geração de padrões de erros do sistema, não

precisando que o operador os adicione manualmente. Técnicas de inteligência artificial e

aprendizado de máquina podem ser utilizadas para relacionar a necessidade de reparo dos

equipamentos com seu histórico de falhas, extraindo assim o padrão de falhas que indica

uma real necessidade de manutenção.

Page 70: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

57

Bibliografia

[1] SOTREQ, “Sotreq,” [Online]. Available: http://sotreq.com.br/.

[2] A. McAfee, “Big Data: The Management Revolution,” Harvard Business Review,

pp. 59 - 68, 2012.

[3] K. Dooley, Designing Large Scale Lans, O'Reilly Media, 2001.

[4] J. M. Rabaey, Digital integrated circuits: a design perspective, Upper Saddle

River, NJ, USA: Prentice-Hall, Inc., 1996.

[5] G. E. Moore, “Cramming more components,” Electronics, vol. 38, nº 8, 1965.

[6] McGill School of Computer Science, “Moore`s law,” [Online]. Available:

https://www.cs.mcgill.ca/~rwest/link-suggestion/wpcd_2008-

09_augmented/wp/m/Moore%2527s_law.htm. [Acesso em 19 dezembro 2016].

[7] B. Barney, “OpenMP,” [Online]. Available:

https://computing.llnl.gov/tutorials/openMP/. [Acesso em 20 dezembro 2016].

[8] B. Barney, “Introduction to Parallel Computing,” [Online]. Available:

https://computing.llnl.gov/tutorials/parallel_comp/. [Acesso em 22 dezembro

2016].

[9] G. M. Amdahl, “Validity of the single processor approach to achieving large scale

computing capabilities,” ACM, pp. 483-485, 1967.

[10] A. S. Tanenbaum e M. V. Steen, DISTRIBUTED SYSTEMS, Upper Saddle

River, N, USA: Prentice-Hall, 2007.

[11] N. Taing, “Parallel and Distributed Computing,” [Online]. Available:

http://lycog.com/distributed-systems/parallel-and-distributed-computing/. [Acesso

em 17 dezembro 2016].

[12] A. Church, “A set of postulates for the foundation of logic,” Annals of

mathematics, pp. 346-366, 1 abril 1932.

[13] École Polytechnique Federale de Lausanne, “Higher-order Functions,” [Online].

Available: http://docs.scala-lang.org/tutorials/tour/higher-order-functions. [Acesso

em 07 novembro 2016].

[14] Microsoft, “Palavra-Chave default em código genérico,” [Online]. Available:

https://msdn.microsoft.com/pt-br/library/xwth0h0d.aspx. [Acesso em 10

novembro 2016].

[15] E. F. CODD, “A relational model of data for large shared data banks,”

Communications of the ACM, vol. 13, nº 6, 1970.

[16] D. D. Chamberlin e R. F. Boyce, “SEQUEL: A structured English query

language,” Proceedings of the 1974 ACM SIGFIDET (now SIGMOD) workshop

on Data description, access and control, pp. 249-264, 01 Maio 1974.

[17] DATASTAX, “Apache Cassandra 2.0 Documentation,” [Online]. Available:

http://docs.datastax.com/en/archived/cassandra/2.0/. [Acesso em 07 novembro

2016].

Page 71: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

58

[18] SOLID IT GMBH, “DB-Engines - Knowledge Base of Relational and NoSQL

Database Management Systems,” [Online]. Available: http://db-engines.com/en.

[Acesso em 16 outubro 2016].

[19] G. Hohpe e B. Woolf, Enterprise Integration Patterns: Designing, Building, and

Deploying Messaging Solutions, Boston, MA, USA: Addison-Wesley Longman

Publishing Co., Inc., 2003.

[20] RED HAT SOFTWARE, “Product Documentation for Red Hat JBoss Fuse,”

[Online]. Available: https://access.redhat.com/documentation/en/red-hat-jboss-

fuse/6.0/. [Acesso em 21 11 2016].

[21] École Polytechnique Federale de Lausanne, “Documentation,” [Online].

Available: https://www.scala-lang.org/documentation/ . [Acesso em 20 novembro

2016].

[22] S. CASS, “The 2016 Top Programming Languages,” [Online]. Available:

http://spectrum.ieee.org/computing/software/the-2016-top-programming-

languages . [Acesso em 20 novembro 2016].

[23] SPARK, “Documentation,” [Online]. Available:

http://spark.apache.org/docs/latest/ . [Acesso em 24 novembro 2016].

[24] SPARK, “Cluster Mode Overview,” [Online]. Available:

http://spark.apache.org/docs/latest/cluster-overview.html. [Acesso em 24

novembro 2016].

[25] SPARK, “Spark Programming Guide,” [Online]. Available:

http://spark.apache.org/docs/latest/programming-guide.html. [Acesso em 02

dezembro 2016].

[26] VISIONLINK, VisionLink VL-Ready API User Guide.

[27] RADIX ENGENHARIA E SOWTWARE, “A Empresa,” [Online]. Available:

http://www.radixeng.com.br/sobre/. [Acesso em 02 Outubro 2016].

[28] SOTREQ, “História,” [Online]. Available: http://sotreq.com.br/empresa2/historia/

. [Acesso em 10 Outubro 2016].

[29] ESSEY, “Parallel Programming with .NET,” Micrososft, [Online]. Available:

https://blogs.msdn.microsoft.com/pfxteam/2009/05/28/partitioning-in-plinq/.

[Acesso em 30 novembro 2016].

Page 72: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

59

Apêndice A

Código da Aplicação

Processador e métodos auxiliares

/*

* PROCESSADOR

*/

import java.util.Date

import org.apache.spark.broadcast.Broadcast

import schemas.OracleTables.{Regra, Violacao}

import Spark.SparkManager._

import com.datastax.spark.connector._

import com.datastax.spark.connector.cql.CassandraConnector

import org.apache.spark.rdd.RDD

import schemas.CassandraTables.{Falha, FalhaTemp}

object Processor {

/*

* Conector com o banco Cassandra

*/

val cassandraConnector = CassandraConnector.apply(sparkContext.getConf)

/*

* Metodo principal da aplicacao

*/

def Processar(regras : Iterable[Regra], bucket: BigInt) : Iterable[Violacao] = {

//Determinar bucktet atual e proximo das falhas temporarias

val bucketAtual = BucketTempAtual()

val proximoBucket = ProximoBucket(bucketAtual)

//Organizar Regras para mapped-join

val regrasExpandidasPorTag = ExpandirRegrasPorTag(regras)

val regrasAgrupadasPorModeloETag =

AgruparRegrasPorModeloETag(regrasExpandidasPorTag)

val regrasAgrupadasPorIdEModelo = AgruparRegrasPorIdEModelo(regrasExpandidasPorTag)

val broadcastRegrasModeloTag = sparkContext.broadcast(regrasAgrupadasPorModeloETag)

val broadcastRegraIdModelo = sparkContext.broadcast(regrasAgrupadasPorIdEModelo)

//Organizar Falhas Para Join

val falhasModeloETag = ObterFalhasCassandraPorModeloETag(bucket)

val falhasTempIdRegraEModelo = ObterFalhasTemporariasCassandraPorIdRegraEModelo()

//Realizar mappped-join

val FalhasERegras = JoinRegrasComFalhas(broadcastRegrasModeloTag, falhasModeloETag)

val FalhasTempERegras =JoinRegrasComFalhasTemp(broadcastRegraIdModelo,

falhasTempIdRegraEModelo)

//Realizar Union das falhas com as falhas temorarias

Page 73: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

60

val unionFalhasERegras = FalhasERegras.union(FalhasTempERegras)

//Realizar Agrupamento por SerialNumber e Regra

val falhasAgrupadas = AgruparFalhasPorSerialNumberERegra(unionFalhasERegras)

//Processar as falhas com as regras

val violacoesEFalhasTemp = ProcessarFalhas(falhasAgrupadas, proximoBucket).cache()

val violacoes = violacoesEFalhasTemp.flatMap(x => x._1)

val falhasTemp = violacoesEFalhasTemp.flatMap(x => x._2)

//Coletar Resultado e Salvar no Cassandra

val violacoesColetadas = violacoes.collect()

falhasTemp.saveToCassandra("sotreq","pr_falhas_temp")

ExcluirFalhasTemporariasAntigas(bucketAtual)

violacoesColetadas

}

/*

* Exclui todas as falhas temporarias com

* o bucket fornecido

*/

def ExcluirFalhasTemporariasAntigas(bucket : BigInt): Unit ={

if(bucket == null)

return

val session = cassandraConnector.openSession()

session.execute("DELETE FROM sotreq.pr_falhas_temp WHERE bucket = " + bucket + " ")

session.close()

}

/*

* Define qual e o proximo bucket

* bucket alterna entre 1 e 2

*/

def ProximoBucket(bucket : BigInt) : BigInt = {

if(bucket == null)

return 1

if( bucket == 1)

return 2

1

}

/*

* Define qual e o bucket das falhas temporarias atual

*/

def BucketTempAtual(): BigInt ={

val falhaTemp =

sparkContext.cassandraTable[FalhaTemp]("sotreq","pr_falhas_temp").first()

if(falhaTemp == null)

return null

falhaTemp.Bucket

}

/*

* Invoca o interpretador e realiza o filtro para definir

* as falhas temporarias

*/

Page 74: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

61

def ProcessarFalhas(falhasERegras : RDD[((String, Int, String), Iterable[Falha])],

proximoBucket : BigInt): RDD[(Iterable[Violacao], Iterable[FalhaTemp])] ={

val violacoesEFalhasTemp = falhasERegras.map(x => {

val violacoesETempoLimite = Interpretador.Interpretar(x._2,x._1._2,x._1._3)

val falhasTemp =

FiltroFalhas.FiltrarFalhasTemporarias(violacoesETempoLimite._2,x._1._2, proximoBucket,

x._2)

(violacoesETempoLimite._1, falhasTemp)

})

violacoesEFalhasTemp

}

/*

* Realiza um agrupamento do conjunto falhas-regras

* reunindo todas as falhas que se relacionam com o

* mesmo numero de serie, Id da regra e sua expressao

*/

def AgruparFalhasPorSerialNumberERegra(falhasERegras :

RDD[((String,String,Int,String,String),Falha)]): RDD[((String, Int, String),

Iterable[Falha])] = {

val agrupamento = falhasERegras.map(x => ((x._1._1, x._1._3, x._1._4), x._2))

.groupByKey()

agrupamento

}

/*

* Realiza uma operacao de Join entre as regras e as falhas temporarias

* O objetivo e fitrar somente as falhas que tenham regras para serem processadas

* e as regras que possuam as falhas correspondentes

* Regras e falhas possuem as mesmas chaves (IdRegra e Tag)

* Chave (SerialNumber, Modelo, IdRegra, Expressao, Tag)

* e valor Falha

*/

def JoinRegrasComFalhasTemp (broadcastRegras: Broadcast[Map[(Int,String),

Iterable[Regra]]], falhas: RDD[((Int,String), FalhaTemp)] )

: RDD[((String,String,Int,String,String),Falha)] = {

//Filtrar os resultados onde nao foi encontrada uma regra correspondente

val joinnedFalhasERegras = falhas.map( falha => (falha._1, falha._2,

broadcastRegras.value.getOrElse(falha._1, null)))

//Sobram agora um conjunto de regras e uma falha que se aplicam ao mesmo RegraId e

Tag

.filter(x => x._3 != null)

//Expande o resultado para futuro agrupamento

.flatMap(x => x._3.map(regra => ((x._2.Serial_number, x._2.Model, regra.Id_regra,

regra.Expressao, x._2.Tag), x._2)))

//TrasformaParaFalha

.map(x => (x._1, new

Falha(x._2.Bucket,x._2.Tag,x._2.Model,x._2.Serial_number,x._2.Timestamp,

x._2.Insert_time)))

joinnedFalhasERegras

}

/*

* Realiza uma operacao de Join entre as regras e as falhas

* O objetivo e fitrar somente as falhas que tenham regras para serem processadas

* e as regras que possuam as falhas correspondentes

* Tanto as regras quanto as falhas possuem as mesmas chaves (Modelo e Tag)

Page 75: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

62

* Chave: (SerialNumber, Modelo, IdRegra, Expressao, Tag)

* Valor: Falha

*/

def JoinRegrasComFalhas (broadcastRegras: Broadcast[Map[(String,String),

Iterable[Regra]]], falhas: RDD[((String,String), Falha)] )

: RDD[((String,String,Int,String,String),Falha)] = {

//Filtrar os resultados onde nao foi encontrada uma regra correspondente

val joinnedFalhasERegras = falhas.map( falha => (falha._1, falha._2,

broadcastRegras.value.getOrElse(falha._1, null)))

//Sobram um conjunto de regras e uma falha que se aplicam ao mesmo Modelo e Tag

.filter(x => x._3 != null)

//Expande o resultado para futuro agrupamento

.flatMap(x => x._3.map(regra => ((x._2.Serial_number, x._2.Model, regra.Id_regra,

regra.Expressao, x._2.Tag), x._2)))

joinnedFalhasERegras

}

/*

* Realiza um agrupamento onde a chave e (IdRegra, Modelo)

* e o valor e uma colecao de Regras que tenham o IdRegra

* e alvo o Modelo

*/

def AgruparRegrasPorIdEModelo (conjuntoRegraTag: Iterable[(Regra, String)]) :

Map[(Int,String), Iterable[Regra]] = {

val agrupamentoPorIdEModelo = conjuntoRegraTag.groupBy(x => (x._1.Id_regra, x._2))

.map(agrupamento => (agrupamento._1, agrupamento._2.map(conjunto => conjunto._1)))

agrupamentoPorIdEModelo

}

/*

* Realiza um agrupamento onde a chave e (Modelo, Tag)

* e o valor e uma colecao de Regras que tenham como alvo o modelo

* e contenham na expressao a tag

*/

def AgruparRegrasPorModeloETag(conjuntoRegraTag : Iterable[(Regra,String)]):

Map[(String,String), Iterable[Regra]] = {

val agrupamentoPorModeloETag : Map[(String,String), Iterable[Regra]] =

conjuntoRegraTag.groupBy(x => (x._1.Modelo, x._2))

.map( agrupamento => (agrupamento._1, agrupamento._2.map(conjunto =>

conjunto._1)))

agrupamentoPorModeloETag

}

/*

* FlatMap sobre as regras, retornando para cada regra um conjunto com a chave

* a propria regra e o valor cada Tag presente na regra

*/

def ExpandirRegrasPorTag(oracleRules: Iterable[Regra]) : Iterable[(Regra,String)] ={

val regrasExpandidas = oracleRules.flatMap(regra =>

ExtrairTagsDaRegra(regra).map(tag => (regra,tag)))

regrasExpandidas

}

/*

* Retorna um RDD de falhas

Page 76: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

63

* Chaves: Modelo, Tag

*/

def ObterFalhasCassandraPorModeloETag(bucket: BigInt): RDD[((String,String), Falha)] =

{

val falhasPorChave : RDD[((String,String), Falha)] =

sparkContext.cassandraTable[Falha]("sotreq", "pr_falhas")

.where("bucket = ?", bucket)

.map(x => ((x.Model, x.Tag), x))

falhasPorChave

}

/*

* Retorna um RDD de falhas temporarias

* Chaves: Id_regra, Modelo

*/

def ObterFalhasTemporariasCassandraPorIdRegraEModelo(): RDD[((Int,String), FalhaTemp)]

= {

val tempoAtual = new Date()

val falhasTempPorChave: RDD[((Int, String), FalhaTemp)] =

sparkContext.cassandraTable[FalhaTemp]("sotreq", "pr_falhas_temp")

.filter(falhaTemp => FiltroFalhas.FalhaTempRecente(falhaTemp,tempoAtual))

.map(x => ((x.Id_regra, x.Model), x))

falhasTempPorChave

}

/*

* Retorna uma colecao das tags envolvidas em cada expressao da regra

*/

def ExtrairTagsDaRegra(r:Regra):Iterator[String] = {

"(\\#[\\w.]+)(?!.*\\1)".r.findAllMatchIn(r.Expressao).map(x => x.group(0))

}

}

Filtro de Falhas

/*

* FILTRO DE FALHAS

*/

import java.util.Date

import schemas.CassandraTables.{Falha, FalhaTemp}

object FiltroFalhas {

/*

* Periodo considerado recente: Uma semana em ms

*/

val periodoRecente : Long = 604800000

/*

* Determina se a falha temporaria e recente

*/

def FalhaTempRecente(falha : FalhaTemp, tempoAtual : Date): Boolean ={

if (tempoAtual.getTime - falha.Insert_time.getTime < periodoRecente)

Page 77: GERENCIAMENTO DE TEXTURAS PARA APLICAÇÕES DE …monografias.poli.ufrj.br/monografias/monopoli10020199.pdf · distribuída, Apache Spark, Cassandra, banco de dados. viii ABSTRACT

64

return true

false

}

/*

* Determina se a falha deve ser salva na tabela de fahas tmporarias

*/

def FiltrarFalhasTemporarias(momentoLmite: Date, IdRegra : Int, bucket: BigInt, falhas

: Iterable[Falha]): Iterable[FalhaTemp] = {

val falhasTemporarias = falhas.filter(falha => falha.Timestamp.getTime >

momentoLmite.getTime )

.map(falha => new FalhaTemp(bucket, falha.Tag, falha.Model,falha.Serial_number,

IdRegra, falha.Timestamp, falha.Insert_time))

falhasTemporarias

}

}

Mapeamento do Banco Oracle

/*

* MAPEAMENTO DO BANCO ORACLE

*/

import java.util.Date

object OracleTables {

case class Regra (Id_regra: Int, Modelo: String, Expressao: String)

case class Violacao (Id_regra: Int, Serial_number: String, Timestamp: Date)

}

Mapeamento do Banco Cassandra

/*

* MAPEAMENTO DO BANCO CASSANDRA

*/

import java.util.Date

object CassandraTables {

case class Falha(Bucket : BigInt, Tag : String, Model:String, Serial_number : String,

Timestamp: Date, Insert_time: Date)

case class FalhaTemp(Bucket : BigInt, Tag : String, Model:String, Serial_number :

String, Id_regra : Int, Timestamp: Date, Insert_time: Date)

}