Diego Liberalquino Soares Lima
ECAMID: UM MIDDLEWARE PARA NUVEM COMPUTACIONAL
COM SUPORTE À ELASTICIDADE
Dissertação de Mestrado
Universidade Federal de Pernambuco
[email protected]
www.cin.ufpe.br/~posgraduacao
RECIFE
2014
Universidade Federal de Pernambuco
Centro de Informática
Pós-graduação em Ciência da Computação
Diego Liberalquino Soares Lima
ECAMID: UM MIDDLEWARE PARA NUVEM COMPUTACIONAL
COM SUPORTE À ELASTICIDADE
Trabalho apresentado ao Programa de Pós-graduação em
Ciência da Computação do Centro de Informática da Universidade Federal de Pernambuco como requisito parcial para
obtenção do grau de Mestre em Ciência da Computação.
Orientador: Nelson Souto Rosa
RECIFE
2014
Catalogação na fonte
Bibliotecária Jane Souto Maior, CRB4-571
L732e Lima, Diego Liberalquino Soares
ECAMID: um middleware para nuvem computacional com
suporte à elasticidade. / Diego Liberalquino Soares Lima. –
Recife: O Autor, 2014.
98 f.: il., fig., tab.
Orientador: Nelson Souto Rosa.
Dissertação (Mestrado) – Universidade
Pernambuco. CIn, Ciência da Computação, 2014.
Inclui referências.
Federal
1. Sistemas distribuídos. 2. Computação em nuvem. 3.
Middleware. I. Lima, Diego Liberalquino Soares (orientador). II.
Título.
004.36
CDD (23. ed.)
UFPE- MEI 2014-190
de
Dissertação de Mestrado apresentada por Diego Liberalquino Soares Lima ao programa de
Pós-Graduação em Ciência da Computação do Centro de Informática da Universidade Federal de Pernambuco, sob o título eCaMid: Um Middleware para Nuvem Computacional
com Suporte à Elasticidade, orientada pelo Prof. Nelson Souto Rosa e aprovada pela banca
examinadora formada pelos professores:
———————————————————————–
Prof. Adilson Barbosa Lopes
Departamento de Informática e Matemática Aplicada/UFRN
———————————————————————–
Prof. Kiev Santos da Gama
Centro de Informática/UFPE
———————————————————————–
Prof. Nelson Souto Rosa
Centro de Informática/UFPE
Visto e permitida a impressão,
Recife, 13 de agosto de 2014
———————————————————————–
Profa. Edna Natividade da Silva Barros
Coordenadora da Pós-Graduação em Ciência da Computação do
Centro de Informática da Universidade Federal de Pernambuco.
Dedico este trabalho aos meus pais, Alexandre e Carmem, e
à minha futura esposa, Pollyana, por todo apoio que me foi
dado nesta jornada repleta de obstáculos.
Agradecimentos
Gostaria de agradecer primeiramente aos meus pais, Carmem e Alexandre, por sempre
estarem do meu lado ao longo deste mestrado, aconselhando-me nos momentos de dúvida,
incentivando-me nos momentos de angústia e colaborando em todas as atividades cotidianas.
Sem o apoio de vocês, jamais teria conseguido iniciar o mestrado, tão pouco manter-se nele face
a todas as adversidades encontradas.
Agradeço também à minha noiva Pollyana, por toda companhia e paciência nestes dois
anos. Ambos estivemos fazendo nossos mestrados neste tempo e compartilhamos os mesmos
momentos de estresse e sacrifício pessoal. Tivemos ainda que nos manter unidos frente às
barreiras de um relacionamento à distância, fruto de nossas escolhas profissionais.
Gostaria de agradecer também a pessoas com quem convivi na minha vida profissional
nestes anos, e que demonstraram toda sua compreensão nesta jornada acadêmica. Por isso
agradeço a Juliano Rabelo e Saulo Cadete da Document Solutions; Rodolfo Max, José Neto,
Alan, Tony, Thiago, Eduardo e Felipe, da Petroquímica Suape; Jefferson, Frederico, Janisson,
Anderson, Helder, Jairo e Cícero da Dataprev.
Além destes quero agradecer a todos os amigos que mantiveram apoio, mesmo com a
minha ausência dos círculos sociais nestes últimos anos, muitos desses que também estavam
enfrentando as dificuldades de um mestrado.
Finalmente, agradeço a Tércio Morais e Nelson Rosa pela parceria nos projetos pesquisas
de middleware e nuvem que estivemos realizando neste período de mestrado.
A distributed system is one in which the failure of a computer you didn’t even
know existed can render your own computer unusable.
—LESLIE LAMPORT
Resumo
Computação em nuvem fornece aplicações, plataformas e servidores virtuais como
serviço, e permite que consumidores paguem pela utilização destes serviços sem que eles
precisem ser adquiridos. Um dos grandes benefícios da computação em nuvem é a elasticidade,
uma vez que consumidores podem requisitar mais recursos sob demanda e liberá-los quando não
são mais necessários. Aplicações distribuídas desenvolvidas em nuvem devem levar em conta a
presença da elasticidade para implementar sua arquitetura e serviços. No entanto, o uso efetivo
da elasticidade por parte das aplicações pode ser complexo e ocasionar vários erros. Utilizando
um middleware orientado a objeto existente (CaMid - Cloud-Aware Middleware), este trabalho
apresenta o projeto e a implementação dos mecanismos básicos para suporte à elasticidade,
tais como: replicação, coordenação de tarefas, compartilhamento de estado e balanceamento
de carga. Estes mecanismos foram incorporados ao CaMid e visam maximizar a utilização
dos recursos de nuvem à medida que estes são adicionados à infraestrutura da aplicação e
mantê-los em funcionamento quando estes recursos são descartados. Para avaliar os mecanismos
desenvolvidos, foi realizada uma avaliação experimental para identificar o impacto dos mesmos
na execução das aplicações. Foi possível verificar que o CaMid conseguiu utilizar os recursos de
nuvem com eficiência a um custo do overhead causado pela coordenação dos vários processos
distribuídos.
Palavras-chave: Sistemas Distribuídos. Computação em Nuvem. Middleware. Elasticidade.
Abstract
Cloud computing offers applications, platforms and virtual servers as a service, and
allows consumers to pay by the use of these services, without requiring their acquisition. One
of the greatest benefits of cloud computing is elasticity, since consumers may request more
resources on demand and release them when they are no longer needed. Distributed applications
developed by the cloud must take in account the presence of elasticity for implementing its
architecture and services. However, the effective use of elasticity by the applications may prove
complex and error prone. By the use of an existing object oriented middleware (CaMid - CloudAware Middleware), this work presents the project and implementation of the basic mechanisms
for supporting elasticity, namely: replication, task coordination, state sharing and load balancing.
These mechanisms have been incorporated to CaMid and aim to maximize cloud resources
utilization while new resources are being added to application infrastructure, or keep working
when the cloud resources are being discarded. In order to evaluate the developed mechanisms,
an experimental evaluation has been done to identify the impact of these mechanisms during
applcation execution. It was possible to verify that CaMid was able to use cloud resources with
efficiency at the overhead cost caused by the coordination of the many distributed processes.
Keywords: Distributed Systems. Cloud Computing. Middleware. Elasticity.
Lista de Figuras
2.1
2.2
Arquitetura dos serviços de nuvem oferecidos pela Google (JIN et al., 2010) . .
Relacionamento entre modelos de computação em nuvem (RIMAL; CHOI;
LUMB, 2010) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Arquitetura Genérica de Middleware . . . . . . . . . . . . . . . . . . . . . . .
2.4 Arquitetura de aplicação multi-camadas . . . . . . . . . . . . . . . . . . . . .
2.5 Invocação de método remoto em um middleware orientado a objetos . . . . . .
2.6 Relacionamento entre padrões de projeto para serviços comuns de um middleware Distributed Object Computing Middleware (DOC) . . . . . . . . . . .
2.7 Arquitetura em camadas do Cloud-Aware Middleware (CaMid), em uma pilha
de serviços de nuvem (MORAIS; LIBERALQUINO; ROSA, 2013) . . . . . .
2.8 Arquitetura dos serviços de gerenciamento do CaMid . . . . . . . . . . . . . .
2.9 Interação do Local Manager com demais camadas do CaMid (MORAIS; LIBERALQUINO; ROSA, 2013) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10 Interação do Global Manager com demais camadas do CaMid (MORAIS; LIBERALQUINO; ROSA, 2013) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
3.12
3.13
Elementos básicos do modelo de domínio do Elastic Cloud-Aware Middleware
(eCaMid) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Visão geral dos componentes do eCaMid. Os elementos de cor branca representam componentes, os de cor cinza representam serviços, enquanto o elemento
preto representa um framework. Os elementos em tracejado são oriundos da
arquitetura do CaMid, enquantos os elementos em linha contínua foram adicionados ao eCaMid. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Estilos de comunicação um-para-um e um-para-muitos . . . . . . . . . . . . .
Modelo de domínio do subsistema de publish-subscribe . . . . . . . . . . . . .
Modelo de domínio do subsistema de escalonamento de tarefas . . . . . . . . .
Modelo de domínio do subsistema de gerenciamento de ciclo de vida . . . . . .
Componentes envolvidos na criação de objetos de sessão. . . . . . . . . . . . .
Componentes envolvidos em uma requisição de método remota. . . . . . . . .
Componentes envolvidos em balanceamento de carga . . . . . . . . . . . . . .
Componentes envolvidos em roteamento de requisições . . . . . . . . . . . . .
Balanceamento de carga no eCaMid . . . . . . . . . . . . . . . . . . . . . . .
Tolerância a falhas no mecanismo de balanceamento de carga. . . . . . . . . .
Diagrama de implantação para nós do eCaMid . . . . . . . . . . . . . . . . . .
23
27
31
32
33
38
42
43
44
45
50
51
53
54
55
57
58
59
60
60
61
62
64
4.1
4.2
4.3
Gráficos de barra para comparação de tempo de resposta médio entre todos os
grupos de experimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Gráficos de barra para comparação de vazão entre todos os grupos de experimentos 78
Tempo de resposta vs tempo do experimento para comparação entre os grupos
de experimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Lista de Tabelas
2.1
2.2
4.1
4.2
4.3
4.4
4.5
4.6
Relações entre classes de Remote Objectse mecanismos de gerenciamento de
recursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Cenários possíveis para falha de um nó e o impacto causado (WILDER, 2012) .
Tempo de resposta e vazão para o grupo de experimentos Direct-Stateless . . .
Tempo de resposta e vazão para o grupo de experimentos Direct-Stateful . . . .
Tempo de resposta e vazão para o grupo de experimentos Elastic-ClusteredStateless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tempo de resposta e vazão para o grupo de experimentos Elastic-Clustered-Stateful
Teste estatístico Mann-Whitney comparando os grupos de experimento ElasticClustered-Stateful e Elastic-Clustered-Stateless . . . . . . . . . . . . . . . . .
Teste estatístico Mann-Whitney comparando os grupos de experimento ElasticClustered-Stateful e Elastic-Clustered-Stateful . . . . . . . . . . . . . . . . . .
35
40
71
72
73
74
76
77
Lista de Acrônimos
AOR
Absolute Object Reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
API
Application Programming Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Amazon VPC Amazon Virtual Private Cloud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
AWS
Amazon Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
WS-BPEL
Business Process Execution Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
CaMid
Cloud-Aware Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
CDMI
Cloud Data Management Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
DDS
Data Distribution Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
DHT
Distributed Hash Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
DOC
Distributed Object Computing Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
EC2
Elastic Compute Cloud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
eCaMid
Elastic Cloud-Aware Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
GAE
Google App Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
GDS
Global Data Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
GFADS
Research Group on Foundations and Applications of Distributed Systems . . . . . 18
IaaS
Infrastructure as a Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
ICME
Intercloud Message Exchange Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
IDS
Intrusion Detection System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
JVM
Java Virtual Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
MIS
Monitoring Information Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
MOM
Message Oriented Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
OCCI
Open Cloud Computing Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
OMG
Object Modeling Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
OSGi
Open Service Gateway initiative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
OVF
Open Virtualization Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26
OWL
Web Ontology Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
P2P
Peer-to-Peer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
PaaS
Platform as a Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
QoS
Quality of Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
REST
Representational state transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
RMI
Remote Method Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
RPC
Remote Procedure Call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
SaaS
Software as a Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
SAN
Storage Area Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
SLA
Service Level Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
SNMP
Simple Network Management Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
SOA
Service Oriented Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
UUID
Universally Unique Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Sumário
1
2
3
Introdução
1.1 O Problema . . . . . . .
1.2 Soluções Parciais . . . .
1.3 Proposta . . . . . . . . .
1.4 Estrutura da Dissertação
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Conceitos Básicos
2.1 Computação em Nuvem . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Categorias de serviço de nuvem . . . . . . . . . . . . . . . . . . .
2.1.1.1 SaaS . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1.2 PaaS . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1.3 IaaS . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1.4 Relacionamento entre modelos de computação em nuvem
2.1.2 Elasticidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Padrões de Projeto de Middleware e Nuvem . . . . . . . . . . . . . . . . .
2.2.1 Arquitetura e Padrões de Projeto para Middleware . . . . . . . . .
2.2.1.1 Middleware Orientado a Objetos . . . . . . . . . . . . .
2.2.1.2 Gerenciamento de Ciclo de Vida . . . . . . . . . . . . .
2.2.1.3 Serviços comuns . . . . . . . . . . . . . . . . . . . . . .
2.2.2 Arquitetura e Padrões de Projeto para Computação em Nuvem . . .
2.2.2.1 Padrões de projeto para computação em nuvem . . . . .
2.3 Cloud Aware Middleware . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1 Local Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.2 Global Manager . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Proposta
3.1 Motivação e Objetivos . . . . . . . . . . . . . . . . .
3.2 Requisitos . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Modelo de domínio geral . . . . . . . . . . . . . . . .
3.4 Arquitetura . . . . . . . . . . . . . . . . . . . . . . .
3.4.1 Coordenação . . . . . . . . . . . . . . . . . .
3.4.1.1 Comunicação Publish/subscribe . . .
3.4.1.2 Escalonamento de tarefas periódicas
3.4.2 Compartilhamento de Estado . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
17
18
19
20
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
22
22
23
25
27
28
29
30
31
33
35
39
40
41
43
44
44
.
.
.
.
.
.
.
.
46
47
48
49
51
52
53
54
55
.
.
.
.
.
56
59
62
64
65
.
.
.
.
.
.
.
66
66
67
69
70
70
74
80
.
.
.
.
.
.
.
.
.
.
.
81
81
81
82
83
84
85
87
88
90
91
92
Considerações Finais
6.1 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
94
3.5
3.6
3.7
4
5
6
3.4.2.1 Gerenciamento de ciclo de vida de objetos remotos
3.4.3 Balanceamento de Carga . . . . . . . . . . . . . . . . . . . .
Tecnologias utilizadas . . . . . . . . . . . . . . . . . . . . . . . . . .
Implantação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . .
Avaliação de Desempenho e Discussão
4.1 Objetivos e Metodologia . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Métricas, Parâmetros e Fatores . . . . . . . . . . . . . . . . .
4.1.2 Técnica de avaliação, carga de trabalho e projeto de avaliação
4.2 Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 Resultados individuais de cada experimento . . . . . . . . . .
4.2.2 Comparação entre resultados . . . . . . . . . . . . . . . . . .
4.3 Discussão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Trabalhos Relacionados
5.1 Tecnologias fundamentais usadas pelo ElasticCamid
5.1.1 JGroups . . . . . . . . . . . . . . . . . . . .
5.1.2 Infinispan . . . . . . . . . . . . . . . . . . .
5.2 Trabalhos de Middleware Desenvolvido para Nuvem
5.2.1 Arquitetura Geral de Middleware . . . . . .
5.2.2 Multitenancy . . . . . . . . . . . . . . . . .
5.2.3 Interoperabilidade . . . . . . . . . . . . . .
5.2.4 Elasticidade . . . . . . . . . . . . . . . . . .
5.2.5 Outros requisitos não funcionais de nuvem .
5.2.6 Discussão . . . . . . . . . . . . . . . . . . .
5.2.7 Considerações finais . . . . . . . . . . . . .
Referências
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
95
16
1
Introdução
Computação em Nuvem é um paradigma que relaciona sistemas distribuídos e computação utilitária. Assim como concessionárias de energia elétrica, que fornecem um serviço
de manutenção e distribuição de energia, provedores de computação em nuvem oferecem uma
diversidade de ativos como serviço, onde esses ativos podem ser aplicativos, plataformas de
software, bancos de dados virtuais, infraestrutura virtual, hardware e outros (JIN et al., 2010).
Da mesma forma que usuários do serviço de energia elétrica, usuários de nuvem pagam pelo uso
do serviço e não pela aquisição desses ativos, que é contabilizada de várias formas, como por
exemplo tempo de uso, quantidade de dados armazenado, tráfego de rede etc.
Uma nuvem é um conjunto de ativos fornecido por um provedor específico e gerenciados pelos seus usuários através de interfaces gráficas, consoles ou Application Programming
Interfaces (APIs). Os provedores escondem detalhes relacionados à manutenção e operação dos
ativos, geralmente oferecendo algum Service Level Agreement (SLA). Se este ativo for uma
plataforma de software, o provedor se encarrega de provisionar a aplicação em uma máquina
física ou virtual, replicar esta instalação em múltiplos nós e assim por diante. Caso o ativo seja
infraestrutura, o provedor se encarrega de gerenciar máquinas virtuais dos usuários em um pool
de máquinas físicas gerenciadas pelo provedor entre outras operações (RIMAL; CHOI; LUMB,
2010).
O que torna a computação em nuvem atraente é a diminuição do investimento necessário
para construir e manter uma infraestrutura de hardware e software, para desenvolver novos
aplicativos e para usar e manter software de terceiros. Empresas como Google oferecem pacotes
de software de produtividade e serviços de email (Google Apps for Business) (HERRICK, 2009),
acessíveis através da internet em poucos cliques, sem a necessidade de instalar e manter esses
aplicativos localmente (MARSTON et al., 2011), em um modelo conhecido como Software as
a Service (SaaS). Outros provedores de nuvem como a Amazon (VARIA; MATHEW, 2012)
permitem a aquisição de infraestrutura, como máquinas e sistemas de armazenamento virtuais
que funcionam de forma similar a uma infraestrutura física, mas sem a necessidade de fazer um
grande investimento inicial tanto em aquisição quanto em instalação que é comum em servidores
físicos.
1.1. O PROBLEMA
17
Além da vantagem da redução do investimento, o modelo de computação em nuvem
permite também evitar o superdimensionamento dos recursos computacionais utilizados. Ativos
de um provedor de computação em nuvem podem ser adquiridos e descartados rapidamente.
Logo, se é previsto um aumento na utilização do serviço, pode ser solicitado a aquisição de novos
ativos. No momento em que estes não forem mais necessários, estes poderão ser descartados e
devolvidos para o provedor. Este conceito inovador de computação em nuvem é chamado de
elasticidade.
Aplicações distribuídas que foram pensadas para o ambiente de nuvem podem se beneficiar do conceito de elasticidade. No modelo tradicional, toda a infraestrutura de software
e hardware deve ser dimensionada de antemão para atender requisitos não funcionais como
desempenho, escalabilidade, disponibilidade e confiabilidade. Essa infraestrutura teria que ser
grande o suficiente para suportar os picos de utilização, mas estaria subutilizada em momentos
de ociosidade. Com a elasticidade, a infraestrutura não precisa ser superdimensionada, mas
pode ser incrementada ou diminuída de acordo com a demanda de recursos computacionais da
aplicação. Esse fato torna os ambientes de computação em nuvem muito mais eficientes no gerenciamento de recursos que infraestruturas tradicionais (MARSTON et al., 2011) (TALUKDER;
ZIMMERMAN; A, 2010).
1.1
O Problema
A elasticidade não apenas é um dos grandes benefícios para aplicações que se apóiam
no modelo de computação em nuvem, mas também um grande desafio para os desenvolvedores.
A arquitetura dessas aplicações precisa ser pensada para que estas possam operar de forma
eficiente e confiável em um ambiente elástico. Atualmente, é possível desenvolver aplicações
elásticas utilizando facilidades específicas de um provedor, sejam essas plataformas ou serviços
específicos, ou através do uso de APIs específicas que permitem a gerência desses recursos por
parte da aplicação.
Provedores de nuvem oferecem diversos modelos de serviço que apóiam o desenvolvimento de software distribuído. Em um deles, chamado Platform as a Service (PaaS), ou
Plataforma como Serviço, o ativo gerenciado consiste em uma plataforma de software, que
oferece um modelo de programação para a construção de uma aplicação. A vantagem deste
modelo é que a plataforma já implementa os mecanismos de elasticidade, fornecendo para
a aplicação um framework ou um conjunto de APIs que devem ser usados para fazer coisas
como armazenar dados ou tratar requisições externas. A desvantagem é que a aplicação estará
fortemente acoplada às APIs, frameworks e serviços específicos oferecidos pelo provedor de
PaaS.
Um outro modelo utilizado para o desenvolvimento de aplicação é conhecido como
Infrastructure as a Service (IaaS), ou Infraestrutura como Serviço. Neste modelo, o provedor
fornece uma infraestrutura virtual, composta por servidores, discos rígidos, balanceadores de
1.2. SOLUÇÕES PARCIAIS
18
carga entre outros. O provedor também oferece um console ou API para gerenciar os recursos
virtuais da nuvem. A vantagem deste modelo é que o usuário pode definir a arquitetura e a
tecnologia utilizada na aplicação e pode estar sempre utilizando as tecnologias mais recentes
(RIMAL; CHOI; LUMB, 2010). A desvantagem é que os ajustes necessários por tornar a
aplicação elásticas precisam ser realizadas pelo usuário, através da gerência de recursos virtuais
através de APIs ou consoles específicos de cada provedor.
Para facilitar a implantação de soluções elásticas, provedores de IaaS também costumam
oferecer serviços específicos que incluem agentes de monitoramento, balanceadores de carga,
sistemas de armazenamento chave/valor entre outros. No entanto, de acordo com o provedor
de IaaS, esses serviços específicos podem não estar presentes ou divergir na forma em que
funcionam. Existe um esforço para padronizar APIs e serviços de provedores de IaaS. Embora
existam diversos padrões para computação em nuvem, sejam estes abertos ou padrões de facto,
muitos deles ainda não são maduros o suficiente ou amplamente adotados (LEWIS, 2013).
Pelos motivos mencionados acima, é bastante difícil desenvolver uma aplicação que seja
executada sobre um provedor de nuvem que possua suporte à elasticidade sem utilizar APIs ou
serviços específicos de cada provedor, visto que muitos desses serviços são incompatíveis entre
si devido à falta de padronização. Desenvolver esses mecanismos de suporte à elasticidade dentro
da própria aplicação distribuída pode ser difícil, dado a uma série de complexidades inerentes
que são características da elasticidade. Além das complexidades inerentes, podemos citar as
complexidades acidentais que são evidenciadas ao misturar lógica do domínio da aplicação
com funcionalidades voltadas para o suporte à elasticidade, violando o princípio de projeto de
software conhecido como Separation of Concerns.
1.2
Soluções Parciais
Middleware é uma solução ligada diretamente ao desenvolvimento de aplicações distribuídas. Tradicionalmente, middleware tem sido empregado para fornecer um modelo de
programação que abstrai diversas complexidades do desenvolvimento de aplicações distribuídas.
Middleware pode ser utilizado para prover serviços que tornem transparentes as complexidades associadas a um ambiente elástico. O uso de middleware em nuvens IaaS pode trazer os
benefícios encontrados em nuvens PaaS, reduzindo o acoplamento com serviços de um provedor
específico e fornecendo uma variedade maior de modelos de programação e tecnologias.
Entre os diversos sistemas de middleware propostos que visam resolver o problema da
elasticidade e que foram testados em nuvens reais, alguns são voltados a domínios específicos,
como é o caso de soluções de computação paralela e em grade (CALHEIROS et al., 2012);
alguns dependem de ferramentas específicas que não estão presentes nos serviços de um provedor
de nuvem (JAYARAM, 2013); outros apenas propõem recursos que refinam o uso de elasticidade,
fornecendo capacidades adicionais (AZEEZ et al., 2010).
Em um trabalho anterior do grupo Research Group on Foundations and Applications of
1.3. PROPOSTA
19
Distributed Systems (GFADS)1 , foi proposto um middleware, que utiliza o paradigma Distributed
Object Computing Middleware (DOC), denominado Cloud-Aware Middleware (CaMid). Este
middleware foi pensado para o ambiente de computação em nuvem e seu principal objetivo é
tornar transparente (invisível) a complexidade de gerenciamento da nuvem para o desenvolvedor
de aplicação distribuída. Os princípios que guiam a arquitetura do CaMid são: cloud-awareness,
ou a capacidade de monitorar e controlar os recursos disponíveis da aplicação; gerenciamento
automático, que é a capacidade de manipular recursos sem intervenção humana direta; suporte
a aplicações cliente-servidor; transparência de localização e acesso; arquitetura baseada em
padrões de projeto (MORAIS; LIBERALQUINO; ROSA, 2013).
O CaMid foi pensado para gerenciar vários aspectos de uma nuvem IaaS, incluindo
aspectos relacionados à elasticidade. Desta forma, o Elastic Cloud-Aware Middleware (eCaMid)
poderia ser usado diretamente por aplicações que utilizam o modelo de objetos distribuídos
que serão implantadas no ambiente de IaaS ou como blocos fundamentais de um PaaS que usa
esse mesmo modelo. No entanto, a sua primeira implementação não possui mecanismos de
tolerância a falhas, como tolerância a falha temporária ou permanente de um nó, assim como
balanceamento de carga e mecanismos mais eficientes de comunicação entre nós.
1.3
Proposta
Este trabalho propõe uma extensão à implementação e arquitetura do CaMid, chamada
eCaMid, que aprimora os mecanismos existentes para ambientes elásticos. Foram adicionados
mecanismos de comunicação em grupo, replicação e balanceamento de carga, que permitem
tomar vantagem da adição dinâmica de nós a uma infraestrutura virtual, assim como tratar de
forma transparente as falhas de comunicação, ou garantir a consistência das informações quando
os mesmos nós são removidos, seja de forma intencional ou por ocasião de falha. Os mecanismos
de suporte à elasticidade do eCaMid não dependem de um provedor específico de IaaS, pois
todas as funcionalidades foram desenvolvidas internamente ao próprio middleware.
O modelo de programação do antigo CaMid foi estendido para permitir o suporte a
objetos stateful, interceptadores, a troca de mensagens entre componentes através de um modelo
publish/subscribe e a execução de tarefas periódicas, coordenadas entre vários nós. Essas novas
funcionalidades apóiam tanto o desenvolvimento de aplicações distribuídas quanto à extensão de
funcionalidades internas ao middleware.
A principal contribuição deste trabalho foi mostrar os benefícios da utilização de comunicação em grupo, replicação e balanceamento de carga em uma arquitetura de middleware
orientado a objeto, tornando-a mais adequada para a utilização em ambientes elásticos de
computação em nuvem.
1 http://www.gfads.org/
1.4. ESTRUTURA DA DISSERTAÇÃO
1.4
20
Estrutura da Dissertação
Este trabalho está dividido em 6 capítulos, incluindo este capítulo introdutório.
Capítulo 2: introduz conceitos básicos úteis para compreender a proposta deste
trabalho, como uma explanação do conceito de nuvem e elasticidade, uma série de
padrões de projeto utilizados em middleware e em computação em nuvem e uma
breve explanação sobre a arquitetura do CaMid,
Capítulo 3: apresenta a arquitetura do eCaMid e como as novas funcionalidades
poderão ser utilizadas em um ambiente elástico,
Capítulo 4: apresenta uma avaliação experimental do eCaMid em um cenário onde a
elasticidade é utilizada,
Capítulo 5: este capítulo apresenta os trabalhos relacionados que também procuram
resolver de alguma forma a problema da elasticidade, e
Capítulo 6: apresenta algumas considerações finais sobre os resultados obtidos neste
trabalho e propõe trabalhos no futuro.
21
2
Conceitos Básicos
Neste capítulo, introduziremos as principais tecnologias necessárias ao entendimento
do eCaMid. Na primeira seção, faremos uma breve discussão sobre o que é computação em
nuvem, o seu modelo de negócio, as principais categorias de serviço de computação em nuvem
e a relação entre essas categorias de serviço, com foco em SaaS, PaaS e IaaS. Faremos uma
conceituação do que é elasticidade, qual a sua importância para computação em nuvem e como
este tipo de solução é implantada nas categorias de serviço discutidas anteriormente.
Na seção seguinte, faremos uma discussão sobre o que é middleware e quais padrões
arquiteturais e de projeto apóiam o seu desenvolvimento. Faremos uma discussão também de vários padrões de projeto que são relevantes para o contexto de aplicação em nuvem. Seguindo esta
seção, apresentaremos o CaMid, quais seus objetivos e princípios, qual sua a arquitetura, e como
esta é apoiada sobre os padrões discutidos na seção anterior. Faremos também uma discussão
sobre as deficiências arquiteturais e de implementação do CaMid em relação à elasticidade.
2.1
Computação em Nuvem
Segundo FOX et al. (2009), computação em nuvem "é a materialização da ideia de
computação utilitária, que tem o potencial de mudar grande parte da indústria de TI, fazendo
com que produtos de software sejam oferecidos como serviço e reduzindo os imensos gastos
com hardware e pessoas para operarem esses equipamentos". Computação em nuvem pode ser
oferecida como uma série de serviços, que oferecem ativos de várias formas, de softwares como
suítes de produtividade como é o caso do serviço Google App Engine (GAE) (HERRICK, 2009) à
plataformas de software e infraestruturas virtuais complexas, como Amazon Web Services (AWS)
(VARIA; MATHEW, 2012). Quando estes serviços são oferecidos através da Internet, por uma
entidade externa, este serviço é chamado de nuvem pública, mas quando é oferecido por um
departamento ou setor de uma mesma corporação, a oferta de serviço é chamada de nuvem
privada.
Computação em nuvem nasceu da necessidade de se operar uma infraestrutura com
eficiência através de recursos de software e hardware escaláveis, em resposta à necessidade de
2.1. COMPUTAÇÃO EM NUVEM
22
negócios que precisam desenvolver rapidamente aplicações com alto desempenho, escalabilidade e disponibilidade, sejam estas aplicações analíticas ou aplicações móveis que precisam de
respostas em tempo real (MARSTON et al., 2011). Conforme várias empresas de tecnologia
ganhavam maturidade na utilização de tecnologias como virtualização e Service Oriented Architecture (SOA), foi possível construir infraestruturas robustas onde operações de rotina, como
aquisição de servidores virtuais, aconteciam de forma automática e transparente (FURHT, 2010)
(JIN et al., 2010). Após o esforço de automatizar a gerência desses ativos, foram criados modelos
de monetização para que estes pudessem ser disponibilizados como serviços.
2.1.1
Categorias de serviço de nuvem
Dependendo do ativo oferecido em um serviço, podem existir vários tipos de ofertas de
computação em nuvem. Há várias taxonomias de computação em nuvem descritas na literatura,
como Hardware as a Service, Data as a Service, Storage as a Service, Business as a Service e
assim por diante. No entanto, dentre todas as taxonomias descritas, três estão sempre presentes:
SaaS, PaaS e IaaS.
2.1.1.1
SaaS
A primeira categoria, Software as a Service (SaaS), trata de aplicações que são disponibilizadas como serviços para um usuário específico, um grupo de usuários ou uma empresa.
A exemplo de aplicativos SaaS, temos o Dropbox DRAGO et al. (2012), um sistema de armazenamento e compartilhamento de arquivos; o já mencionado Google Apps for Business
HERRICK (2009), um pacote de software que inclui e-mail, criação de documentos como textos
e apresentações e compartilhamento de arquivos; redes sociais como Facebook1 , que permitem
o compartilhamento de mensagens, imagens e videos; serviços de streaming, que incluem o
Grooveshark2 e Netflix3 . Há várias características que geralmente estão presentes em aplicativos
fornecidos como SaaS: todos estes são acessíveis pela Internet, através de vários dispositivos,
permitem algum tipo de troca de informações entre os seus usuários ou possuem modelos de
assinatura que permitem pagar mais para obter algum tipo de vantagem no serviço.
Esses aplicativos geralmente possuem requisitos não funcionais complexos, como disponibilidade, escalabilidade, desempenho e confiabilidade. Além destes requisitos, esses aplicativos
precisam ser constantemente atualizados, corrigindo defeitos rapidamente e oferecendo novas
funcionalidades e recursos. Desenvolver plataformas de software e hardware que sejam capazes
de suportar esses requisitos não funcionais é um dos grandes desafios para os provedores de
SaaS.
1 http://www.facebook.com
2 http://www.grooveshark.com
3 http://www.netflix.com
2.1. COMPUTAÇÃO EM NUVEM
23
Figura 2.1: Arquitetura dos serviços de nuvem oferecidos pela Google (JIN et al., 2010)
2.1.1.2
PaaS
A segunda classificação de serviço oferecido em computação em nuvem, Platform as a
Service (PaaS), consiste em uma plataforma de software que um framework ou uma API que
possibilita o desenvolvimento de aplicações distribuídas. Usuários desses serviços implantam a
aplicação na plataforma e definem parâmetros que informam a quantidade de recursos necessários,
enquanto o provedor do serviço se encarrega de provisionar a infraestrutura necessária para os
níveis desejados de Quality of Service (QoS). Cada oferta de PaaS varia bastante de provedor
para provedor conservando, contudo, algumas semelhanças. Discutiremos sobre dois populares
serviços de PaaS, GAE (SANDERSON, 2009) e Heroku (KEMP; GYGER, 2013), para entender
como funcionam as ofertas de PaaS.
O serviço GAE, Figura 2.1, fornece ao desenvolvedor uma plataforma voltada para
aplicações Web. Cada aplicação web é executada em um sandbox, um ambiente que restringe o
acesso da aplicação a funcionalidades como acesso a arquivos, limitando-a a utilizar requisições
HTTP para páginas presentes na Web, na própria aplicação ou no GAE. Para utilizar outros
serviços, como armazenamento de dados, e-mail, XMPP e outros, deve-se utilizar as APIs
fornecidas pelo serviço, que por sua vez se encarrega de alocar recursos e distribuir as várias
partes da aplicação de forma transparente, garantindo sua escalabilidade. O usuário é cobrado
pelos recursos que utiliza do serviço.
Google não revela em detalhes a arquitetura de sua oferta de PaaS, e não existe na
literatura uma descrição detalhada dos componentes e como estes interagem para tornar a
aplicação disponível. É possível que a solução utilize uma espécie de middleware que provê
acesso a todas APIs oferecidas e de algum outro serviço que trata de distribuir a aplicação entre
2.1. COMPUTAÇÃO EM NUVEM
24
várias máquinas, que podem ser físicas ou virtuais.
Pelo modelo de cobrança adotado no GAE, é possível verificar que cada porção da
aplicação é monitorada, desde o acesso a sua datastore (chamada Bigtable), que contabiliza
número de leituras e escritas, requisições HTTP para serviços externos, logging e outros. O
usuário, contudo, não tem controle sobre a quantidade de recursos utilizados numa aplicação
GAE e pode apenas indicar o valor máximo que deseja pagar pelo serviço. Este tem a autonomia
de ditar quantas instâncias serão necessárias e qual a forma de balanceamento de carga usada,
por exemplo.
A plataforma Heroku suporta aplicações Web escritas em diferentes linguagens de
programação (Java, Ruby, Python, Node.js e outras), onde essa aplicação deve ser dividida em
vários pedaços a serem executados em containers chamados dynos. De forma similar ao GAE,
um dyno representa um sandbox ou container que isola uma aplicação de outra em uma estrutura
virtual, mas sem as mesmas restrições que foram mencionadas anteriormente no GAE.
Existem dois tipos principais de dynos, um Web Dyno, que é responsável por receber
requisições web externas e um Worker Dyno que executa algum processo auxiliar, como uma
rotina batch ou um processo que consome mensagens de uma fila. Dessa forma é possível criar
aplicações que dividem tarefas entre diversos processos distribuídos. Além dos dois tipos de
dynos mencionados, o Heroku oferece outros dynos especializados que atuam como bancos de
dados e servidores de mensagem, por exemplo (KEMP; GYGER, 2013).
Cada dyno é executado em uma stack, um conjunto de máquinas virtuais que contém
configurações idênticas – sistema operacionais na mesma versão, com versões específicas
das linguagens e softwares utilitários da plataforma instalados. Um gerenciador de processos
distribuídos é utilizado para escalonar os dynos em cada máquina virtual do stack. Cada usuário
pode verificar quais dynos estão em execução em um determinado momento.
O modelo de cobrança utilizado no Heroku é mais simples do que aquele utilizado no
GAE. O usuário é cobrado por cada dyno utilizado e um preço mais específico para os dynos
especializados. O usuário no Heroku tem mais controle dos recursos que utiliza, que determina
quantos dynos serão utilizados e de que tipo. Além disso o Heroku também oferece APIs de
serviços para que os dynos sejam monitorados pelo usuário e agentes que reinicializam dynos
que se encontrem inoperantes ou com o desempenho degradadao (KEMP; GYGER, 2013).
Diferente da plataforma GAE, que restringe à aplicação o uso de APIs mais restritas e
uma arquitetura específica, o Heroku dá total liberdade ao usuário de usar qualquer tecnologia
desde que seja compatível com as configurações definidas no stack. Em contrapartida, o
framework ou tecnologia utilizados devem ser adaptar ao ambiente fornecido pelo Heroku,
de forma similar ao que acontece com ofertas de IaaS. O diferencial do Heroku em relação
aos serviços de IaaS é que este oferece um ambiente pré-configurado, e o gerenciamento e a
implantação das aplicações seguem uma arquitetura de processos.
Além dessas ofertas de PaaS, outros serviços merecem destaque. A plataforma Elastic
Beanstalk é parte do catálogo AWS e é composto de várias máquinas virtuais pré-configuradas
2.1. COMPUTAÇÃO EM NUVEM
25
com software específico, com serviços de escalabilidade automática (VARIA; MATHEW, 2012).
A plataforma Tsuru4 é uma implementação open source do Heroku, que pode ser implantada
em instalações privadas de IaaS. De forma similar, Cloud Foundry5 é outro PaaS open source
voltado para infraestruturas privadas.
De forma geral, podemos observar que os PaaS podem ser compostos de middleware
específico e de um serviço de gerenciamento que é responsável por provisionar este middleware
em uma infraestrutura física ou virtual.
2.1.1.3
IaaS
Além das ofertas de PaaS, ainda há provedores que fornecem infraestrutura ao usuário
de nuvem. Essas infraestruturas utilizam virtualização, uma tecnologia que permite simular o
funcionamento de hardware através de software. Como os ativos virtuais são constituídos de
dados, eles podem ser armazenados, copiados e versionados. O público alvo das ofertas de
Infrastructure as a Service (IaaS) são organizações que precisam implantar aplicações de alta
escalabilidade com alto controle sobre a tecnologia utilizada, sem ter que lidar com o custo de
aquisição, implantação e manutenção de hardware.
Diferentemente das ofertas de PaaS, os ativos oferecidos pelos serviços de IaaS são mais
homogêneos, e geralmente são servidores, discos rígidos, redes privadas e balanceadores de
carga. Além desses ativos, os provedores costumam oferecer serviços mais específicos, como o
Amazon Cloudwatch (VARIA; MATHEW, 2012), da suíte AWS, que é usada para monitorar
os recursos da aplicação e servir de métrica para outros serviços da AWS, como Auto Scaling.
Os serviços específicos costumam ser exclusivos de cada provedor, alguns oferecem serviços
ligeiramente similares. Todos os provedores de nuvem disponibilizam uma API que pode ser
usada para gerenciar esses ativos.
Os serviços disponibilizados pelos provedores de IaaS podem ser divididos em 4 categorias: processamento, armazenamento, rede virtual, e serviços específicos. O serviço de
processamento é a base de todos os serviços de IaaS. Este permite o gerenciamento, monitoramento, cópia e provisionamento de servidores virtuais. O provedor oferece os servidores em
vários tamanhos, dependendo da quantidade de processadores, memória RAM e capacidade de
armazenamento. Usuários e fornecedores externos fornecem pacotes que contém um sistema operacional e uma distribuição de software, conhecidos como imagens, que também são gerenciadas
pelo provedor de IaaS. Todos os provedores de IaaS oferecem o serviço de poder computacional,
incluindo nuvens públicas (AWS) e privadas (Openstack6 , Opennebula7 , Eucalyptus8 .
A segunda categoria de serviço IaaS trata de armazenamento de dados. É comum que
o provedor ofereça este serviço de duas formas distintas: como um serviço de gerenciamento
4 http://www.tsuru.io
5 http://cloudfoundry.org
6 http://www.openstack.org
7 http://www.opennebula.org
8 http://www.eucalyptus.com
2.1. COMPUTAÇÃO EM NUVEM
26
de blocos virtuais, como o AWS Elastic Block Store, Openstack Cinder e Eucalyptus Storage
Controller; ou um serviço de armazenamento chave-valor, tais como AWS Simple Storage
Service, Openstack Swift e Eucalyptus Walrus. O primeiro é utilizado como discos rígidos
virtuais que aumentam a capacidade de armazenamento de uma máquina virtual, enquanto o
armazenamento de chave-valor pode ser usado para armazenar imagens de máquinas virtuais
ou diretamente por aplicações distribuídas, sob a forma de bancos de dados não relacionais.
Serviços de armazenamento de bloco dependem de estruturas da infraestrutura física, como
Storage Area Networks (SANs), enquanto servidores de armazenamento chave-valor são bancos
de dados completos, particionáveis e de alta escalabilidade.
Além da capacidade de oferecer máquinas virtuais e armazenamento, os provedores de
nuvem também oferecem redes virtuais, como é o caso dos serviços Amazon Virtual Private
Cloud (Amazon VPC) (VARIA; MATHEW, 2012) e Openstack Neutron (OPENSTACK CLOUD
ADMINISTRATOR GUIDE, 2014). Esses software permitem a emulação de redes virtuais,
como roteadores e switches qua atuam na camada de rede, dispositivos de firelwall e outros.
Através desse softwares é possível separar a infraestrutura em várias camadas, como é o caso de
separar servidores de aplicação e banco de dados em camadas distintas.
Existe uma grande variedade de serviços específicos fornecidos por fornecedores de
IaaS. O provedor AWS possui um grande catálogo de serviços, como balanceamento de carga,
provisionamento automático (auto scaling), monitoramento (Cloudwatch) entre outros. Outros
fornecedores de IaaS públicos, como Google Compute Cloud 9 oferecem serviços similares.
No espaço de fornecedores de IaaS privados, temos Eucalyptus e Openstack que fornecem
balanceamento de carga através do Network Controller e Neutron, respectivamente.
Nem todos os serviços mencionados são unanimidade em provedores de IaaS. Opennebula e Cloudstack, por exemplo, oferecem apenas os serviços de poder computacional e
armazenamento (apenas discos virtuais). Para que uma aplicação utilize o potencial oferecido
pela nuvem, ela deve conhecer quais as facilidades oferecidas pelo provedor; para se manter
independente, é necessário que esta possua mecanismos para se adaptar às diferentes ofertas de
serviço.
A maioria das iniciativas de padronizar a Computação em Nuvem estão voltadas para o
modelo de IaaS, por conta da similaridade dos serviços oferecidos por diferentes provedores, de
acordo com a categoria do serviço. Temos Open Cloud Computing Interface (OCCI) 10 , uma
iniciativa para padronizar as APIs voltadas para o controle de máquinas virtuais; Cloud Data
Management Interface (CDMI) 11 , uma API para serviços de armazenamento de dados; Open
Virtualization Format (OVF) 12 que define formatos específicos para os metadados de máquinas
virtuais, permitindo que estas sejam migradas de um provedor para outro (LEWIS, 2013).
9 https://cloud.google.com/products/compute-engine/
10 http://occi-wg.org
11 http://www.snia.org/cdmi
12 http://www.dmtf.org/standards/ovf
2.1. COMPUTAÇÃO EM NUVEM
27
Figura 2.2: Relacionamento entre modelos de computação em nuvem (RIMAL; CHOI;
LUMB, 2010)
2.1.1.4
Relacionamento entre modelos de computação em nuvem
É possível observar uma possível relação entre as ofertas de SaaS, PaaS e IaaS. O
modelo de SaaS precisa ser capaz de suportar uma grande quantidade de usuários e manter
alta disponibilidade, uma vez que seus serviços podem estar sendo usados por um usuário em
qualquer parte do mundo, em diferentes horários. Para isso, uma oferta de SaaS precisa ser
construída sobre uma plataforma que forneça esses requisitos, como o oferecido em um modelo
de PaaS. Este, por sua vez, precisa de uma infraestrutura eficiente que suporte a elasticidade e
provisionamento rápido de recursos, como numa oferta de IaaS. Essa relação entre serviços pode
ser ilustrada na Figura 2.2.
Não necessariamente um serviço oferecido por um modelo está apoiado por outro modelo
de computação em nuvem. Não há evidências de que o GAE opere sobre um serviço de IaaS.
Na verdade, o GAE foi desenvolvido anos depois da plataforma mencionada. Contudo, existem
provedores públicos de PaaS que utilizam a infraestrutura de provedores de IaaS, como é o caso
do Heroku, que opera sobre a infraestrutura provida pela AWS. O Software chamado CloudApp
13 é uma aplicação que segue o modelo SaaS, especializada em compartilhamento de imagens,
documentos, video e outros ativos, através da plataforma Heroku. Outros provedores de SaaS,
13 http://www.getcloudapp.com/
2.1. COMPUTAÇÃO EM NUVEM
28
como Netflix 14 , possuem uma plataforma própria e preferem utilizar a infraestrutura da AWS
diretamente.
2.1.2
Elasticidade
Uma das consequências de computação em nuvem foi a conversão de despesas de
capital em despesas operacionais (FOX et al., 2009), direcionando os investimentos que antes
eram realizados em hardware e soluções de alto poder computacional para despesas de pessoal e
ferramentas para gerenciar o potencial de computação em nuvem. Este fator se deve a elasticidade,
uma vez que é possível obter recursos da nuvem e depois descartar uma parte quando estes não
estão sendo utilizados.
Em uma infraestrutura tradicional, existe o custo associado à aquisição de recurso
(hardware), instalação e operação da infraestrutura. Esta deve ser bem planejada para evitar
tanto o risco de se ter uma infraestrutura saturada ou subutilizada. Geralmente, o uso médio do
poder computacional da infraestrutura física costuma variar entre 5% e 20% (SIEGELE, 2008),
mas durante picos de utilização, o uso do poder computacional pode aumentar numa dimensão
de duas a dez vezes. Supondo que durante uma parte do dia sejam necessários 500 servidores
para atender a demanda de acesso de uma aplicação (pico), mas no resto do tempo apenas 100
servidores sejam necessários, com uma média de 300 servidores necessários por dia; para se
manter disponível e não degradar o desempenho da aplicação durante o pico de utilização, seria
necessária uma infraestrutura 1.7 vezes maior do que a média de uso dos servidores (FOX et al.,
2009). O paradigma de computação em nuvem, devido à elasticidade, oferece uma forma de
mitigar o risco involvido no dimensionamento da infraestrutura, fornecendo a possibilidade de
adicionar ou remover novas máquinas virtuais em minutos, ao invés de semanas ou meses em
infraestruturas tradicionais.
Utilizar a elasticidade com eficiência não é uma tarefa fácil. BABAR; CHAUHAN
(2011) menciona os desafios de migrar uma aplicação chamada Hackystat15 , desenvolvida
em uma infraestrutura tradicional, para uma infraestrutura ou plataforma fornecida por um
provedor de nuvem. Para escolher a arquitetura da solução, quatro requisitos foram levados em
conta. O primeiro requisito está relacionado à possibilidade de aumentar ou diminuir o tamanho
da nuvem de acordo com critérios de desempenho. O segundo requisito estava relacionado
à portabilidade da aplicação para diferentes provedores de nuvem, que deveriam suportar as
tecnologias utilizadas pela aplicação. O terceiro requisito se referia a portabilidade de dados
(persistência), aos mecanismos de persistência de diferentes provedores. O quarto requisito se
referia a necessidade de uma visão única do sistema: embora a infraestrutura fosse dinâmica,
com vários componentes replicados, deveria ser possível acessar todas essas réplicas como um
único componente.
14 http://www.netflix.com
15 http://csdl.ics.hawaii.edu/research/hackystat/
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
29
Para atender esses requisitos foram realizadas modificações na arquitetura da Hackystat.
Foram utilizados os serviços de IaaS, uma vez que ofertas de PaaS não possibilitavam utilizar as
tecnologias utilizadas no Hackystat. Foi necessário separar os componentes de lógica de negócio
e persistência para que fosse possível criar réplicas do primeiro e o segundo fosse adaptável a
múltiplos provedores de IaaS. Além da persistência, foi criado um componente que orquestrava
as requisições do Hackystat para as réplicas criadas em diferentes máquinas virtuais (BABAR;
CHAUHAN, 2011).
2.2
Padrões de Projeto de Middleware e Nuvem
Aplicações executadas no ambiente de computação em nuvem estão dentro do grande
grupo que compreende os sistemas distribuídos. O que diferencia sistemas distribuídos de
aplicações tradicionais é que um único sistema está dividido em um ou mais processos, que se
comunicam através de mensagens, que possuem espaços de memória distintos e interagem juntos
com um objetivo único (GHOSH, 2010).
As vantagens de um sistema distribuído sobre sistemas monolíticos são: localização geográfica distribuída, em que várias aplicações em diferentes localidades podem trocar informações
entre si; desempenho e escalabilidade, onde tarefas que seriam realizadas em um processo podem
ser divididas entre vários; compartilhamento de recursos, onde múltiplos processos compartilham
recursos em comum, como é o caso de bancos de dados compartilhados; e tolerância a falhas,
uma vez que a falha em um processo pode ser compensada pela existência de um outro processo
redundante (SCHMIDT et al., 2013) (VÖLTER; KIRCHER; ZDUN, 2005).
Apesar de todos os benefícios, o desenvolvimento de sistemas distribuídos apresenta
uma série de desafios. Existem complexidades inerentes e acidentais relacionadas a sistemas
distribuídos. Entre as complexidades inerentes temos a necessidade de lidar com falhas parciais
de um sistema, qualidade de serviço, deadlock distribuídos, sincronização entre outros. Entre as
complexidades acidentais estão as limitações das ferramentas de de desenvolvimento de software
para lidar com esse cenário, além da falta de APIs portáveis entre diferentes infraestruturas.
Um outro problema é a reinvenção e redescobertas de conceitos e técnicas voltadas para desenvolvimento de aplicações distribuídas: existe na indústria de sistemas distribuídos vários
protocolos, bibliotecas, sistemas operacionais entre outros que resolvem os mesmos problemas
e são geralmente incompatíveis entre si (SCHMIDT et al., 2013). Muitas dessas soluções são
proprietárias, sem utilizar padrões abertos já difundidos na indústria.
Tradicionalmente, Middleware tem sido empregado para tornar transparentes as complexidades inerentes de um sistema distribuído, fornecendo, ao mesmo tempo, um modelo
de programação mais abstrato que pode ser utilizado pelos desenvolvedores desses sistemas.
Existem várias categorias de Middleware, dependendo do tipo de modelo de programação utilizado: O modelo de Remote Procedure Call (RPC) torna a comunicação entre dois processos
bastante similar à invocação de funções, onde o cliente fornece uma série de parâmetros e o
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
30
servidor retorna uma resposta; o modelo DOC, é uma especialização do modelo RPC, onde as
primitivas utilizadas são invocações de métodos de objetos, onde estes podem possuir estado
e ser compostos de outros objetos; e o modelo Message Oriented Middleware (MOM), onde
filas de mensagem são utilizadas como primitiva, onde produtores e consumidores de mensagens
utilizam essas filas para se comunicar de indiretamente (VÖLTER; KIRCHER; ZDUN, 2005).
O desenvolvimento de Middleware tem sido fortemente apoiado por padrões de projetos.
Estes representam um conjunto de boas práticas no projeto do software, pois já foram testados
e provados ao longo dos anos, tornando-se soluções refinadas. Padrões de projeto também são
utilizados para compor um vocabulário utilizado para compartilhar conhecimento e experiência
sobre possíveis problemas computacionais e suas soluções (GAMMA et al., 1993). Existe uma
extensa literatura sobre a aplicação desses padrões a sistemas distribuídos: SCHMIDT et al.
(2013) inclui padrões para lidar com concorrência e programação de redes; VÖLTER; KIRCHER;
ZDUN (2005) mostra os componentes fundamentais para a construção de Middleware orientado
a objeto; e HOHPE; WOOLF (2004) menciona um conjunto de padrões para integrar diferentes
sistemas utilizando mensagens e comunicação assíncrona.
Existem padrões de projeto e de arquitetura para aplicações distribuídas que utilizam o
paradigma de computação em nuvem (WILDER, 2012) (HOMER et al., 2014) (REESE, 2009).
WILDER (2012) ilustra diversas soluções para problemas comuns de computação em nuvem,
como escalabilidade horizontal, auto-escalabilidade, consistência eventual, tolerância a falhas,
entre outros. O foco deste trabalho está voltado para o desenvolvimento de aplicações que
nasceram neste ambiente e precisam ser pensadas para tirar proveito de todos os benefícios
concedidos pelo paradigma de computação em nuvem.
2.2.1
Arquitetura e Padrões de Projeto para Middleware
Enquanto middleware pode ser definido de várias formas e é descrito de várias maneiras
na literatura, podemos utilizar uma arquitetura genérica, baseada em camadas, para descrever
sua estrutura, como é ilustrada na figura 2.3. Entre as camadas dispostas na figura, podemos
evidenciar os dispositivos de Hardware e Sistemas Operacionais e Protocolos, que compreendem
todas as APIs e mecanismos de baixo nível que envolvem a comunicação de rede e entre
processos de um mesmo sistema operacional. A última camada, constituída pela aplicação,
compreende toda a lógica de domínio, que por sua vez utiliza todas as camadas abstratas de
middleware para realizar comunicação.
As camadas que se localizam entre a camada de infraestrutura e a serviços específicos
compreendem todas as funcionalidades que estão disponíveis em um middleware. A camada
de infraestrutura, é responsável por encapsular mecanismos de baixo nível de um sistema
operacional e programação de rede. Entre os mecanismos encapsulados, temos a programação
de sockets, gerenciamento de eventos e concorrência. Esta camada também precisa lidar com
diferenças entre APIs de sistemas operacionais. A camada de infraestrutura oferece para a camada
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
31
Figura 2.3: Arquitetura Genérica de Middleware
de distribuição uma série de componentes reusáveis, independentes de sistema operacional, que
fornecem mecanismos de entrada e saída de dados e gerenciamento de conexões (SCHMIDT,
2002).
A camada de distribuição esconde todos mecanismos de gerenciamento de conexões
e entrada e saída de dados para oferecer abstrações de alto nível como filas de mensagens e
objetos remotos. Utilizando essas abstrações é possível desenvolver aplicações distribuídas
que funcionam de forma similar a aplicações monolíticas, que são executadas sobre um único
processo (SADJADI; MCKINLEY, 2003).
A camada de serviços comuns reside sobre a camada de distribuição, oferecendo funcionalidades ligadas a requisitos não funcionais da aplicação, como tolerância a falhas, qualidade
de serviço, logging, persistência, segurança e transações. Enquanto a camada de distribuição se
preocupa com particularidades do modelo de programação, a camada de serviços específicos
realiza a gerência de vários recursos distribuídos entre vários processos, tendo uma visão do
todo. Os serviços oferecidos nesta camada podem ser reusados em diferentes tipos de aplicações,
independentemente de seu domínio.
Os serviços específicos tratam de funcionalidades voltadas a um determinado domínio,
voltados a requisitos funcionais e não funcionais. Entre os serviços específicos utilizados em
middleware temos o controle de transações financeiras, controles de aviação (radar, navegação,
controle de armamento), entre outros (SCHMIDT, 2002).
2.2.1.1
Middleware Orientado a Objetos
Middleware Orientado a Objetos (MOO) é utilizado para comunicação cliente-servidor
que utiliza objetos como principal abstração. Existem várias tecnologias de MOO, como CORBA,
RMI, EJB, DCOM (EMMERICH; KAVEH, 2002). Embora esta tecnologia seja aplicável em
muitos domínios distintos, é comum encontrá-la em aplicações cliente-servidor multi-camadas,
como pode ser observado na figura 2.4. Aplicações multi-camada utilizam comunicação síncrona
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
32
Figura 2.4: Arquitetura de aplicação multi-camadas
(request-reply) entre camadas, com suporte a serviços intermediários tais como balanceamento
de carga, segurança e gerenciamento de transações GORTON (2011).
O cliente manipula objetos localmente em sua aplicação quando, de fato, este objeto está
localizado no lado servidor. O objeto do lado do cliente é um Proxy, um objeto que não contém
nenhuma lógica de domínio, que delega todas as invocações de métodos executadas no cliente
para o objeto localizado no servidor. Este objeto se chama Remote Object, um objeto que possui
lógica de domínio, pode possuir estado e tem seu ciclo de vida controlado pelo servidor.
Um Proxy delega requisições de cliente a um componente conhecido como Requestor.
Este transforma a requisição de um cliente em uma mensagem, que é encapsulada e delegada a
um componente chamado Client Request Handler. Este componente, por sua vez, se encarrega
de entregar a mensagem ao servidor utilizando mecanismos de rede. De forma similar, no lado
servidor, um componente chamado Server Request Handler recebe uma mensagem e entrega a
mesma ao Invoker, que a desencapsula, obtém a instância do Remote Object, e faz uma chamada
de método local a este objeto. Os componentes chamados Marshallers são responsáveis por
codificar as mensagens para um stream de bytes e decodificar este stream de bytes em uma
mensagem, que será entregue entre do cliente para o servidor e vice-versa. Este processo pode
ser observado com a figura 2.5 (VÖLTER; KIRCHER; ZDUN, 2005).
O conjunto formado pelo Requestor, Invoker, Client Request Handler e Server Request
Handler são componentes básicos de uma estrutura maior, chamada de Broker. Além da
comunicação propriamente dita, o Broker também está encarregado de gerenciar o ciclo de vida
dos objetos e fornecer ganchos para as chamadas dos serviços específicos e de domínio.
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
33
Figura 2.5: Invocação de método remoto em um middleware orientado a objetos
2.2.1.2
Gerenciamento de Ciclo de Vida
Um Remote Object funciona de forma similar a um objeto comum em uma linguagem
orientada a objetos, com suporte à composição, delegação herança, polimorfismo e outras
características. O que diferencia Remote Objects de objetos locais é que o estado destes, por
conta da dinâmica da comunicação entre cliente e servidor, precisa ser gerenciado pelo Broker.
Em um ambiente de uma linguagem orientada a objetos, podem ser utilizados mecanismos de
alocação de memória manual ou um garbage collector, que retira da memória objetos que não
estão sendo utilizados. Em uma aplicação cliente-servidor, podem haver milhares de clientes e
Remote Objects. Contudo, um cliente pode ser desconectado por conta de uma falha interna na
rede. O Broker, no entanto, não pode simplesmente descartar o objeto por conta de uma queda
de conexão, pois o cliente poderia tentar se reconectar e continuar a operação de negócio que
estava realizando antes. Ao mesmo tempo, a parte servidor do Broker não pode manter o objeto
na memória indefinidamente, pois isso poderia provocar o esgotamento de recursos do sistema
operacional e consequentemente na queda do servidor.
Por esse motivo, Remote Object s são classificados de três formas diferentes, como Static
Instances, Per-Request Instances e Client-Dependent Instances (VÖLTER; KIRCHER; ZDUN,
2005). Static Instances, são objetos que preservam seu estado independentemente do cliente
que os consulta e sua memória é preservada durante toda a existência do Broker. Esta estratégia
é útil quando a vida deste objeto está ligada diretamente a existência de um dispositivo físico
ou processo. No entanto, a existência de muitas Static Instances podem levar ao esgotamento
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
34
de memória do sistema operacional. Um outro problema relacionado a Static Instances é que
estes devem manter seu estado consistente mesmo após inúmeras chamadas remotas de diversos
clientes, levando a problemas de concorrência.
Uma forma de evitar totalmente os problemas de concorrência e esgotamento de memória
de Static Instances, é não preservar nenhum estado no Remote Object. Per-Request Instances são
objetos que são criados no escopo de uma chamada remota de método. Dessa forma, esses PerRequest Instances podem ser acessados livremente sem problemas de concorrência, consistência
ou esgotamento de memória. A desvantagem de sua utilização é que pode existir a necessidade
de guardar estado dentro da aplicação, tornando esta estratégia inútil para esta finalidade.
Uma terceira classificação representa o meio termo entre o uso de Static Instances e
Per-Request Instances. Client-Dependent Instances representam objetos que existem pelo tempo
de vida de um cliente. Estes objetos são criados quando um cliente inicia uma conexão com a
aplicação e destruídos quando essa conexão é terminada. Client-Dependent Instances reduzem os
problemas de concorrência se comparados a um Static Instances, pois este objeto será acessado
por um único cliente. As desvantagens dessa abordagem é que se existirem centenas de clientes,
centenas de Client-Dependent Instances serão criados. O Broker também não pode certeza
absoluta de quando uma conexão é terminada, pois esta pode ser resultado de uma falha de
comunicação na rede e não de uma desconexão. Um outro problema é que Client-Dependent
Instances não estão totalmente imunes a problemas de concorrência, pois uma aplicação pode
ser acessada por múltiplas interfaces utilizando uma mesma conexão.
Além das estratégias básicas, o Broker pode utilizar diferentes mecanismos de gerenciamento de recursos dependendo da estratégia de ciclo de vida utilizada. O primeiro mecanismo
Lazy Acquisition (VÖLTER; KIRCHER; ZDUN, 2005) se refere em adiar a criação de um
Remote Object apenas quando uma chamada para este é realizada. Esse mecanismo faz com que
o estado de um Remote Object somente seja alocado na memória quando este for realmente ser
utilizado. Este padrão é útil para todas as estratégias de ciclo de vida de objetos.
Um segundo mecanismo de gerenciamento de recursos é o uso de Pooling (VÖLTER;
KIRCHER; ZDUN, 2005), ou a criação de um pool de objetos que podem ser reutilizados. Este
mecanismo evita o overhead causado pela criação e destruição de um objeto remoto, otimizando
a utilização de recursos do sistema operacional. Pooling é melhor utilizado para objetos que
não possuem identidade ou estado e são tratados de forma igual, como é o caso de Per-Request
Instances. Pooling pode também ser utilizado para objetos com estado, desde que este seja
alocado dinamicamente pelo Broker.
O terceiro mecanismo de gerenciamento de recursos se chama Leasing (VÖLTER;
KIRCHER; ZDUN, 2005) e consiste em atribuir um tempo de expiração para a alocação de um
Remote Object em memória. Caso esse objeto não seja acessado durante o tempo de expiração,
o mesmo é destruído. Este recurso é essencial quando se usa a estratégia Client-Dependent
Instance, eliminando objetos alocados por um cliente quando estes não estão sendo utilizados.
O último mecanismo de gerenciamento de recursos é chamado de Passivation (VÖLTER;
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
35
KIRCHER; ZDUN, 2005) e consiste no armazenamento permanente de um objeto seguido da
desalocação do estado da memória. Este recurso é útil ao utilizar uma Static Instance, para
liberar a utilização de memória nos casos desses objetos estarem sendo pouco acessados.
A Tabela 2.1 mostra a relação entre as três classificações de Remote Objectse os mecanismos de ciclo de vida que podem ser utilizados por cada um:
Tabela 2.1: Relações entre classes de Remote Objectse mecanismos de gerenciamento de
recursos
Static Instance
Lazy Acquistion útil
Pooling
inútil
Leasing
pouco útil
Passivation
pouco útil
Per-Request Intance
implicitamente útil
muito útil
inútil
inútil
Client-Dependent Instance
implicitamente útil
pouco útil
muito útil
muito útil
O Broker utiliza um componente específico para lidar com o gerenciamento de ciclo de
vida, chamado Lifecycle Manager (VÖLTER; KIRCHER; ZDUN, 2005). Este componente é
responsável por criar e gerenciar Remote Objectse utilizar, de acordo com a sua categoria, os
mecanismos de gerenciamento de recurso adequados. Adicionalmente, o Lifecycle Manager
pode prover uma série de callbacks para que a aplicação execute ações específicas durante
algumas etapas do ciclo de vida.
2.2.1.3
Serviços comuns
Um middleware DOC dispõe de vários serviços que podem ser utilizados para tratar de
requisitos de qualidade, como transparência de localização, tolerância à falhas e monitoramento
de qualidade de serviço. Três padrões de projeto podem ser usados com essa finalidade, Lookup
e Location Forwarding e QOS Observer.
Uma das vantagens principais de middlewares DOC é a transparência de localização,
onde um cliente pode acessar um Remote Object sem definir exatamente a localização. O serviço
de Lookup é usado justamente para esta finalidade: ele utiliza uma estrutura de dados que é usada
para armazenar a localização de objetos em diferentes servidores. Cada Remote Object possui um
identificador lógico único no middleware, este chamado de Absolute Object Reference (AOR),
que é vinculado a dados de localização pelo serviço de Lookup. A partir desse identificador, o
serviço de Proxy consegue descobrir a localização exata de um Remote Object em uma rede.
Sem esse identificador lógico, o cliente precisaria informar dados de localização daquele objeto,
como IP e porta (como na pilha de protocolos TCP/IP) (VÖLTER; KIRCHER; ZDUN, 2005).
O Serviço de Lookup possui pelo menos três primitivas, como pode ser visto na Listagem
2.1:
Listagem 2.1: Interface de Serviço de Lookup
p u b l i c i n t e r f a c e Lookup {
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
36
void r e g i s t e r ( A b s o l u t e O b j e c t R e f e r e n c e aor ,
Endpoint endpoint ) ;
void u n r e g i s t e r ( AbsoluteObjectReference aor ) ;
Endpoint find ( AbsoluteObjectReference aor ) ;
}
A primeira primitiva, chamada register, é utilizada para vincular um AOR a um endereço
de rede, chamado endpoint, que representa a localização física do objeto na rede. A segunda,
unregister é utilizada para retirar um AOR do serviço de Lookup. A primitiva find consiste
na utilização de uma AOR para obter a localização física (endpoint) de um objeto remoto.
Obtendo essa informação é possível construir um Proxy que faça referência a um Remote Object
correspondente (BUSCHMANN; HENNEY; SCHMIDT, 2007).
Será necessário para o cliente a localização física do serviço de Lookup. O processo de
obtenção dessa localização é chamado de bootstrapping. O bootstrapping pode ser resolvido de
várias formas, seja fornecendo manualmente as informações de localização ou mais elaborada,
através de um broadcast (KIRCHER; JAIN, 2004).
Além da transparência de localização, é importante garantir que um Remote Object
esteja sempre disponível mesmo que um processo servidor falhe temporariamente. Isso pode ser
realizado a partir da utilização de várias réplicas do mesmo objeto em diferentes servidores. Esta
estratégia é útil não somente para evitar a indisponibilidade, mas também para distribuir a carga
de requisições de maneira eficiente entre todas as réplicas.
O padrão de projeto Location Forwarder (VÖLTER; KIRCHER; ZDUN, 2005) pode
ser utilizado para esta finalidade. Este pode ser concebido como um protocolo onde o cliente
recebe uma mensagem de redirecionamento e procura a nova réplica de objeto remoto, ou como
um componente que se encarrega de enviar requisições para a réplica adequada, agindo como
um intermediário entre o cliente e o objeto remoto. A vantagem da primeira abordagem é a
descentralização dos mecanismos de redirecionamento. A desvantagem é que a concepção de
um protocolo de redirecionamento pode ser complexo, e o middleware não possui controle total
da distribuição de carga entre as várias réplicas. A segunda abordagem, de se utilizar o Location
Forwarder como um componente, é a possibilidade de se utilizar várias abordagens complexas
de balanceamento de carga; a desvantagem desta abordagem é presença de um ponto único de
falha, em caso de indisponibilidade deste componente.
Além do mecanismo de redirecionamento de requisições, pode ser usado um protocolo
de gerenciamento de grupos para gerenciar todas as réplicas existentes de um Remote Object. O
padrão de projeto Object Group (MAFFEIS et al., 1996) é utilizado para esta finalidade: este
define um protocolo onde um Broker pode registrar uma réplica específica em um grupo. O
Object Group substitui um AOR de um Remote Object em um serviço de Lookup: ao invés de
localizar cada objeto individualmente, o serviço de Proxy passa a registrar a referência de um
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
37
grupo. Requisições destinadas a este Object Group são redirecionada a algum dos membros
registrados ou a todos. Um componente de Location Forwarding poderia ser utilizado nesse
aspecto, provendo mecanismos eficientes de balanceamento de carga.
O protocolo utilizado por um Object Group é dividido em gerenciamento de membros,
gerenciamento de view e compartilhamento de estado. O gerenciamento de grupos é realizado a
partir das primitivas create_group, destroy_group, join e leave, que permitem, respectivamente,
a criação de um Object Group, sua destruição, a entrada de um membro e a saída deste.
Uma view é uma representação do estado atual de um Object Group, e contém uma
referência para cada membro. Quando um novo membro se junta ou deixa um Object Group,
todos os membros existentes recebem uma nova view, indicando quais são os participantes. Cada
membro da view é identificada de forma única, e este recurso de identidade pode ser utilizado
para selecionar um coordenador do Object Group.
As primitivas get_state e set_state são utilizadas para compartilhar o estado de um Remote
Object entre todos os membros de um Object Group. A primitiva get_state é utilizado por um
dos membros do Object Group para compartilhar o estado atual do objeto. A primitiva set_state é
utilizada para os novos membros do grupo, que obterão o estado atual das réplicas. As primitivas
de compartilhamento de estados são particularmente úteis para efetuar a migração de um Remote
Object de uma localização para outra.
A Listagem 2.2 ilustra as primitivas de comunicação de um Object Group agrupadas em
uma interface de uma linguagem oritentada a objeto:
Listagem 2.2: Primitivas de comunicação do padrão Object Group
c l a s s GroupBOA : v i r t u a l p u b l i c BOA {
s t a t i c v o i d c r e a t e _ g r o u p ( O b j e c t _ p t r group ,
c o n s t P r o t o c o l P o l i c y& p o l i c y
=default_potocol_policy );
void j o i n ( O b j e c t _ p t r group ) ;
void l e a v e ( O b j e c t _ p t r group ) ;
s t a t i c void de st ro y_ g ro up ( O b j e c t _ p t r group ) ;
v i r t u a l v o i d g e t _ s t a t e ( AnySeq& s t a t e ,
B o o l e a n& done ) ;
v i r t u a l v o i d s e t _ s t a t e ( c o n s t AnySeq& s t a t e ,
B o o l e a n& done ) ;
v i r t u a l v o i d v i e w _ c h a n g e ( c o n s t View& newView ) ;
}
A qualidade de serviço apresentada por um middleware orientado a objetos deve ser
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
38
Figura 2.6: Relacionamento entre padrões de projeto para serviços comuns de um
middleware DOC
monitorada. Entre os itens que podem ser monitorados estão o Server Request Handler, o
Invoker e cada Remote Object individualmente. O padrão de projeto QOS Observer (VÖLTER;
KIRCHER; ZDUN, 2005) é usado justamente para esta finalidade, coletar métricas específicas
de cada componente do middleware orientado a objetos.
Para que o QOS Observer seja utilizado corretamente, o desenvolvedor do middleware
deve prover um gancho específico para cada componente a ser medido. Este gancho deve
funcionar de forma semelhante àquela encontrada no padrão de projeto Observer (GAMMA
et al., 1993), onde é criado um Subject para cada gancho, que por sua vez registra vários QOS
Observers. Quando acontece uma mudança de estado no Subject, este envia uma notificação
a todos os QOS Observers registrados. Cada QOS Observer , por sua vez, consulta o estado
do Subject e coleta uma série de métricas, como tamanho da mensagem, tempo de execução e
quantidade de invocações (VÖLTER; KIRCHER; ZDUN, 2005).
A figura 2.6 ilustra os serviços comuns abordados nesta seção, e seu relacionamento.
Verificamos que o serviço de Proxy pode registrar uma referencia a um Object Group e este
pode usar um Location Forwarder para distribuir requisições entre várias réplicas de um mesmo
Remote Object . Também observamos quais componentes de um middleware DOC podem ser
monitorados por QOS Observers.
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
2.2.2
39
Arquitetura e Padrões de Projeto para Computação em Nuvem
Aplicações desenvolvidas para o ambiente de computação em nuvem possuem diferenças
arquiteturais fundamentais. Elas são particionadas e executadas em vários nós, ao invés de um
único grande máquina física. Devem ser possível adicionar ou remover recursos computacionais
com facilidade e continuar funcionando corretamente quando este fato acontece. Utilizam comunicação assíncrona e uma arquitetura fracamente acoplada. São constantemente monitoradas
mesmo quando nós são descartados.
Conceitualmente, um nó representa uma unidade lógica de um sistema, que possui
recursos de hardware. A lógica de aplicações é executada em nós computacionais e seus dados
armazenados em nós de dados. Um nó pode ser representado por uma máquina física, uma
máquina virtual ou um cluster de várias máquinas. Em nuvens IaaS, nós representam máquinas
virtuais (WILDER, 2012).
Um dos requisitos não funcionais que aplicações em ambiente de nuvem necessitam é
escalabilidade, que pode ser dividida em dois tipos não mutuamente exclusivos: escalabilidade
vertical ou escalabilidade horizontal. A escalabilidade vertical trata do aumento da capacidade de
nós existentes, enquanto a horizontal se refere a adição de novos nós à infraestrutura da aplicação.
Escalabilidade é tanto uma necessidade de aplicações transacionais, que lidam com acessos de
milhares de usuários simultaneamente, mas também de aplicações analíticas que precisam lidar
com grandes volumes de dados em tempo real (REESE, 2009).
Uma das vantagens de um ambiente de nuvem é a ilusão de escalabilidade infinita
decorrente da elasticidade, sobretudo em nuvens públicas. No entanto, não é possível tirar
proveito desta escalabilidade se a arquitetura da aplicação não é inerentemente escalável (VARIA,
2010). A contenção de recursos em uma aplicação pode limitar a sua capacidade de alcançar a
escalabilidade, gerando gargalos em pontos específicos como acesso a dados ou conexão de rede
(WILDER, 2012).
A arquitetura de aplicação nativa de nuvem também deve ser projetada para lidar com
falhas. Uma máquina virtual pode se tornar indisponível após receber uma grande carga de
acessos, os dados armazenados em um nó podem ser perdidos, o balanceador de carga pode
falhar, um mestre numa configuração mestre-escravo pode falhar. A melhor maneira de lidar
com falhas de infraestrutura é tornar a próprio software resiliente (VARIA, 2010).
A tabela 2.2 exibe uma série de cenários onde a falha em um nó pode ocasionar na falha
da aplicação. A falha em um nó pode ser causada por um problema de hardware (infraestrutura física), alguma operação interna do provedor ou alguma solicitação do administrador da
aplicação.
A melhor estratégia para lidar com este cenário é assumir sempre o pior caso, onde o
nó será perdido e os dados locais também. Se um único nó pode falhar, devem haver diversas
réplicas redundantes de um mesmo nó. Este também não poderá armazenar dados localmente. A
aplicação não deve parar de funcionar por conta da falha de um nó. Caso exista a necessidade de
2.2. PADRÕES DE PROJETO DE MIDDLEWARE E NUVEM
40
Tabela 2.2: Cenários possíveis para falha de um nó e o impacto causado (WILDER,
2012)
Cenário
Falha súbita +
reinicialização
Desligamento de nó +
reinicialização
Desligamento de nó +
reinicialização
Desligamento de nó +
terminação
Alerta
Impacto
Prévio
Dados locais são
Falha súbita de hardware
Não
perdidos
Provedor de nuvem (substituição de
Dados locais podem
Sim
hardware, atualização de software)
estar disponíveis
Aplicação (atualização, bug e
Dados locais
Sim
reinicialização gerenciada)
estão disponíveis
Dados locais
Aplicação (destruição de um nó)
Sim
estão perdidos
Iniciado Por
manter estado na aplicação, este estado deve ser compartilhado com os outros nós, através da
utilização de um serviço de armazenamento compartilhado (WILDER, 2012).
Deve ser possível iniciar aplicações em nuvem com o mínimo de esforço, automatizando
o processo de iniciação e implantação. Isso pode ser realizado através da criação de imagens e
de scripts de inicialização. Deve ser realizado monitoramento constante dos recursos utilizados
pela aplicação, a fim de obter métricas que representem a qualidade de serviço da aplicação.
Por fim, é necessário definir uma estratégia para automatizar a inicialização de novos nós da
aplicação seja com base em carga de trabalho, sazonalidade ou algum outro fator influenciado
pela qualidade de serviço (VARIA, 2010) (WILDER, 2012) (BALIGA et al., 2011) (MARSTON
et al., 2011).
2.2.2.1
Padrões de projeto para computação em nuvem
No trabalho desenvolvido por HOMER et al. (2014), podemos identificar vários padrões
de projeto que são relevantes para o desenvolvimento de aplicações em nuvem. Serão citados
aqueles que foram utilizados na arquitetura proposta por este trabalho.
A partir dos princípios arquiteturais vistos anteriormente, é possível destacar que aplicações executadas em ambiente de nuvem precisam ser particionadas e ter tarefas divididas entre
vários nós. No entanto, às vezes é preciso que uma tarefa seja executada unicamente em toda
a aplicação distribuída. Para realizar este tipo de operação é necessário coordenar as várias
réplicas para que apenas uma seja capaz de executar a tarefa em questão. O padrão de projeto
Leader Election (HOMER et al., 2014) é usado para esta finalidade. É escolhido um líder entre
os vários processos existentes e este líder é responsável por executar aquela tarefa entre todos
os nós existentes. O líder pode ser um processo fixo ou pode ser utilizado um mecanismo de
sincronização – como um lock distribuído.
Existe a necessidade de monitorar a saúde de todos os nós de uma aplicação de nuvem,
para saber se cada um está operando corretamente, visando garantir a disponibilidade da aplicação.
O padrão de projeto Health Endpoint Monitoring (HOMER et al., 2014) consiste na utilização de
checagens funcionais para os vários nós da aplicação e receber uma indicação de funcionamento
2.3. CLOUD AWARE MIDDLEWARE
41
correto. Existem várias formas de realizar esta checagem, seja utilizando códigos de status ou
examinando o conteúdo de respostas para analisar se foi recebida a resposta correta.
Deve haver cuidado em como o monitoramento da aplicação pode ser realizado. Se o
agente de monitoramento realizar checagens muito frequentes, poderá comprometer o funcionamento da aplicação. O próprio agente de monitoramento pode estar com prolemas, logo, é
importante que este faça checagens em seus próprios módulos. esporadicamente.
Como falhas são inerentes a uma aplicação em um ambiente computação em nuvem,
ao utilizar um serviço, este pode apresentar uma falha total ou temporária. Os padrões de
projeto Retry e Circuit Breaker (HOMER et al., 2014) consistem, respectivamente: em um
mecanismo para evitar falhas temporárias de serviço através da utilização de um mecanismo
onde a requisição realizada pelo cliente é tentada novamente; na utilização de condições que
evitam a comunicação com um serviço que está aparentemente em mal funcionamento. Os
padrões funcionam de forma complementar, onde o Circuit Breaker evita que a ocorrência de
um Retry em um serviço que está aparentemente desabilitado.
2.3
Cloud Aware Middleware
O Cloud-Aware Middleware (CaMid) MORAIS; LIBERALQUINO; ROSA (2013) é um
trabalho de pesquisa desenvolvido pelo grupo Research Group on Foundations and Applications
of Distributed Systems (GFADS) com a finalidade de desenvolver um middleware orientado a
objetos que possui mecanismos de gerenciamento de nuvem que funcionassem de forma automática e transparente a uma aplicação. O trabalho desenvolvido por MORAIS; LIBERALQUINO;
ROSA (2013) apresenta as seguintes contribuições: uma arquitetura de middleware baseada em
camadas de middleware consolidada na literatura (SCHMIDT, 2002); utilizar os serviços de
nuvem para aprimorar os mecanismos de distribuição (transparência de localização e acesso,
modelo de comunicação); integrar as várias camadas de nuvem verticalmente, como uma camada
ortogonal a IaaS, PaaS e SaaS; tornar o gerenciamento da nuvem transparente, como parte dos
mecanimsos de distribuição.
Os princípios que guiam a arquitetura do CaMid são: cloud-awareness ou ciência de
nuvem, a capacidade de monitorar e controlar os recursos disponíveis da aplicação de forma
transparente, incluindo virtualização, elasticidade e outros; gerenciamento automático, que
é a capacidade de manipular recursos sem intervenção humana direta; suporte a aplicações
cliente-servidor multi-camada; transparência de localização e acesso; arquitetura baseada em
padrões de projeto consolidados (MORAIS; LIBERALQUINO; ROSA, 2013). A arquitetura
do CaMid é divida em três camadas, e serve como um dos componentes de um PaaS , em um
ambiente de aplicação em nuvem, como pode ser observado na figura 2.7.
2.3. CLOUD AWARE MIDDLEWARE
42
Figura 2.7: Arquitetura em camadas do CaMid, em uma pilha de serviços de nuvem
(MORAIS; LIBERALQUINO; ROSA, 2013)
O CaMid implementa a arquitetura de um middleware DOC. A camada de infraestrutura
do CaMid serve como uma interface para as APIs de programação em rede do sistema operacional
de uma máquina virtual. Ela é composta de dois componentes principais, o Client Request
Handler e um Server Request Handler , que encapsulam mecanismos de comunicação, como o
estabelecimento de conexões de rede e transmissão de dados. A camada de distribuição provê
transparência de acesso à aplicação, fornecendo uma abstração de middleware orientado a objeto,
utilizando os componentes Proxy, Requestor, Invoker, Remote Object e Marhsaller. Na camada
de serviços o CaMid provê uma série de serviços reusáveis que são utilizados para aprimorar
o gerenciamento do sistema como um todo. Seus serviços estão divididos em duas categorias,
serviço de nomes e serviço de gerenciamento. O serviço de nomes implementa o padrão de
projeto Lookup, enquanto o serviço de gerenciamento é utilizado para promover a ciência de
nuvem.
Os serviços de gerenciamento providos pelo CaMid foram divididos de acordo com seu
contexto. O contexto local consiste em operações locais, requisições, migração de serviços
e desempenho. O contexto global inclui todos os nós de um sistema, incluindo aplicações e
recursos de infraestrutura. Neste contexto, o serviço de gerenciamento, utilizando a API de
gerenciamento de nuvem, nomeada como o componente IaaS Manager, monitora todos os
recursos da nuvem, como o número de VMs ativas, sua localização e o desempenho da rede
virtual. Dados coletados dos contextos locais e globais são identificados por uma chave, que é
composta de um Universally Unique Identifier (UUID), informação de contexto, tipo de recurso,
id do recurso e localização.
A quantidade de informações obtidas do IaaS Manager depende do provedor. Alguns
fornecem informação completa, como máquina virtual, localização na estrutura física, enquanto
outros limitam as informações fornecidas, como é o caso de informações de hardware em
provedores de nuvem pública.
A figura 2.8 representa os componentes de gerenciamento do CaMid e sua interação com
as demais camadas. São dois componentes principais de gerenciamento, o Local Manager, para
2.3. CLOUD AWARE MIDDLEWARE
43
Figura 2.8: Arquitetura dos serviços de gerenciamento do CaMid
o contexto local e o Global Manager no contexto global. O Local Manager é subdividido em
dois outros componentes, o Local Monitor, que monitora os recursos de qualidade da aplicação e
o Local Controller que gerencia os recursos internos do nó, como o número de threads ativas
e objetos remotos. O Local Manager notifica o Global Manager periodicamente, fornecendo
informações locais como métricas de desempenho dos componentes de distribuição e objetos
remotos, uso de CPU do sistema virtualizado, entre outros. O Global Manager interage com o
IaaS Manager para obter informações adicionais da infraestrutura de nuvem, envia instruções
para os Local Managers e podem atualizar informações no contexto de Local Managers.
2.3.1
Local Manager
A figura 2.9 ilustra os componentes do Local Manager, que consistem no Monitoring
Information Service (MIS) , os Observers e o Local Controller. Os Observers são uma realização
do padrão de projeto QOS Observer, e é utilizado para coletar informações de qualidade dos
componentes da camada de infraestrutura, camada de distribuição, objetos remotos e sistema
operacional virtual. Estes podem ser divididos em System Observers, que coletam informações
do sistema operacional, como CPU e memória. É utilizado também para informar inconsistências
entre as leituras das apis do IaaS Manager. Os Handler Observers são responsáveis por monitorar
as requisições, incluindo as métricas vazão e tempo de resposta de todo o middleware. Os Invoker
Observers coletam informações da camada de distribuição, mais precisamente do componente
Invoker. Por fim, os Remote Service Observers visam a coleta de métricas dos objetos remotos,
como tempo de resposta. O MIS coleta informações dos Observers e registra essas informações
em tabelas internas, e usa os componentes da camada de distribuição para enviar e receber
informações ao Global Manager. O MIS e os Observers constituem o componente Local
2.4. CONSIDERAÇÕES FINAIS
44
Figura 2.9: Interação do Local Manager com demais camadas do CaMid (MORAIS;
LIBERALQUINO; ROSA, 2013)
Monitor.
O Local Controller executa ações demandadas pelo Global Manager, incluindo a inicialização de objetos remotos, atualização de informações do sistema (localização de nós e
desalocação de recursos de IaaS .
2.3.2
Global Manager
A arquitetura do Global Manager é ilustrada na figura 2.10. O Global Manager é
responsável pelo monitoramento e controle do sistema como um todo. O IaaS Requestor
requisita informações da nuvem IaaS, como as máquinas virtuais existentes e informação de
monitoramento de cada uma delas, como tamanho da memória, CPU, ferramenta de virtualização
utilizada. Da mesma forma que os IaaS Requestors, os Global Managers recebem informações
de cada Local Manager específico. Nos dois casos, cada pedaço de informação é coletado por
um Observer específico.
As informações dos dois componentes são consolidas no Information Processor, combinando as informações obtidas. Essas informações podem servir de insumo para ações que podem
ser acionadas através do Global Controller. É responsabilidade do Global Controller suportar a
alocação e retirada de máquinas virtuais, replicação dos objetos remotos em novas instâncias de
máquinas virtuais e balanceamento de carga.
2.4
Considerações Finais
Neste capítulo, foi apresentado o conceito de computação em nuvem, quais suas vantagens a respeito de infraestruturas tradicionais e suas características. Foi realizada uma catego-
2.4. CONSIDERAÇÕES FINAIS
45
Figura 2.10: Interação do Global Manager com demais camadas do CaMid (MORAIS;
LIBERALQUINO; ROSA, 2013)
rização de cada modelo de oferta de serviço de computação em nuvem – SaaS, PaaS e IaaS –
observando as vantagens e desvantagens de cada um e como estes modelos se relacionam.
Foi realizada uma revisão dos conceitos de middleware, qual a sua definição e quais
modelos de comunicação possíveis, ilustrando uma arquitetura que compreende suas camadas
principais – infraestrutura, distribuição, serviços comuns e serviços específicos. O modelo de
middleware orientado a objetos (ou middleware DOC) foi analisado e foram descritos os seus
componentes principais através de padrões de projeto documentados na literatura, incluindo
padrões relativos a gerenciamento de ciclo de vidas de objetos remotos serviços comuns. Observamos algumas caracterísiticas fundamentais de aplicações desenvolvidas para computação
em nuvem, onde foi citada a necessidade de utilizar uma arquitetura tolerante a falhas, tornar a
aplicação fácil de implantar e utilizar scripts de automação baseados em sazonalidade.
Por fim, foram introduzidos os princípios arquiteturais do CaMid, os padrões de projeto
que o apóiam e os seus componentes principais.
Estes tópicos formam os conceitos básicos necessários para entender a motivação e a
proposta deste trabalho, e serão utilizadas para justificar as escolhas tomadas pelo desenvolvimento dos mecanismos de suporte a elasticidade do CaMid, que serão mencionados no próximo
capítulo.
46
3
Proposta
Construir uma aplicação para nuvem, que possa tirar proveito da elasticidade não é uma
tarefa simples. A aplicação deve ser pensada para estar particionada em vários nós diferentes.
Deve ser possível adicionar mais nós à infraestrutura facilmente e ter benefícios imediatos na
escalabilidade do sistema. A aplicação deve continuar disponível mesmo quando um nó torna-se
indisponível, seja esta devido a uma falha acidental ou devido ao desligamento manual solicitado
pelo usuário de nuvem. Os vários componentes da aplicação também precisam coordenar suas
atividades, saber como escalonar tarefas paralelas e possuir capacidade de se comunicar de forma
assíncrona. Caso a aplicação precise manter estado, este deve ser compartilhado entre todos os
nós, para evitar que a queda de um ocasione em indisponibilidade dos serviços oferecidos pela
aplicação. Esses são os princípios básicos que tornam uma aplicação adequada a um ambiente
elástico de computação em nuvem.
A arquitetura do CaMid (MORAIS; LIBERALQUINO; ROSA, 2013) prevê o suporte à
elasticidade, mas não menciona os componentes ou serviços que oferecem este suporte. Neste
capítulo vamos detalhar as extensões realizadas à arquitetura do CaMid para que este possa se
beneficiar das vantagens proporcionadas pela elasticidade. O CaMid, acrescido deste conjunto
de extensões, será chamado de Elastic Cloud-Aware Middleware (eCaMid).
A próxima seção apresenta os princípios que guiaram o desenvolvimento do Elastic
Cloud-Aware Middleware (eCaMid). Em seguida iremos definir os requisitos necessários para o
suporte à elasticidade. Será proposta uma arquitetura que utilize três mecanismos de suporte
à elasticidade: comunicação em grupo, que trata da capacidade de gerenciar um grupo de nós,
verificando quais desses nós são membros ativos do grupo, provendo meios eficientes de troca
de mensagens entre eles e coordenando a execução de tarefas em um ambiente distribuído;
replicação, a capacidade de criar nós redundantes que compartilham estado; e balanceamento de
carga, que visa distribuir as requisições de uma aplicação entre as diversas réplicas, evitando a
sobrecarga de um nó único.
Serão detalhadas também as tecnologias utilizadas para a concepção dos mecanismos de
elasticidade e de que forma o middleware pode ser implantado em uma infraestrutura de nuvem.
3.1. MOTIVAÇÃO E OBJETIVOS
3.1
47
Motivação e Objetivos
O CaMid (MORAIS; LIBERALQUINO; ROSA, 2013) é um middleware orientado a
objetos. Logo, seu modelo de programação é baseado em objetos remotos que são compostos por
outros objetos que se comunicam através de chamadas de método. Objetos podem ou não conter
estado e caso possuam, este estado deve ser gerenciado pelo middleware, evitando que objetos
sejam armazenados indefinidamente na memória. Objetos e suas réplicas estarão distribuídos
entre vários nós e as requisições realizadas pelos clientes podem ser balanceadas entre os nós
existentes. Deve ser possível ainda acessar o estado de cada objeto em todos os nós, evitando
que a falha de um no ocasione na indisponibilidade na aplicação.
A primeira implementação do CaMid (MORAIS; LIBERALQUINO; ROSA, 2013)
introduziu vários componentes importantes: Naming Service, Global Manager, Local Manager e
as camadas de comunicação e distribuição. O Naming Service e Global Manager, particularmente,
são componente centrais do CaMid, por isso, eles devem sempre estar replicados para evitar que
alguma falha nestes ocasione na parada completa do middleware.
Os componentes de gerenciamento do CaMid, Global Manager e Local Manager coletam informações do ambiente através de Observers, mas a comunicação entre processos do
middleware ainda acontece através de chamadas de método remotas. O CaMid deveria intermediar a comunicação entre Subjects (objetos que são monitorados e geram eventos) e Observers,
provendo um estilo de comunicação assíncrono, através da troca de mensagens. Deve ser possível enviar mensagens de um componente localizado em um nó a outro presente em outro
nó, utilizando um estilo de comunicação Publish/Subscribe. Publishers publicam mensagens
através de uma fila, enquanto os Subscribers tratam essas mensagens. Este estilo de comunicação
também pode ser utilizado pela aplicação, que pode combinar o estilo de troca de mensagens
com à chamada de métodos de objetos remotos.
Os componentes de gerenciamento do CaMid também precisam executar tarefas em
intervalos periódicos. Os System Observers, componentes do Local Manager no CaMid responsáveis por captar informações de utilização de CPU e memória, dependem de agentes que
obtêm informações periodicamente do sistema operacional. Os Observers do Global Manager
também dependem de agentes que obtém informações do IaaS Requestor periodicamente. Estes
componentes estarão dispersos em vários nós, portanto as tarefas desempenhadas por estes
agentes devem ser coordenadas. Essas tarefas podem ser executadas localmente em cada nó,
ou devem ser executadas uma vez para um grupo de nós. As aplicações também devem poder
utilizar este recurso, implementando seus próprios agentes.
Estes mecanismos do CaMid precisam ser aprimorados para tomar vantagem da elasticidade. No capítulo anterior, foram citadas algumas características fundamentais que uma
aplicação distribuída precisa ter para que tome vantagem do paradigma de computação em nuvem:
particionamento em múltiplos nós; capacidade de adicionar ou remover nós dinamicamente;
preservação do comportamento da aplicação em caso de falha de um nó; modelo de comunicação
3.2. REQUISITOS
48
escalável e fracamente acoplado sem contenção de recursos.
Por isso, o eCaMid estende a arquitetura original, visando cumprir os seguintes objetivos:
3.2
Aprimorar os mecanismos de coordenação entre os nós existentes, sabendo quais
objetos foram publicados em cada nó e quando um nó está ativo ou inativo.
Realizar balanceamento de carga entre os nós, de forma que um único nó não seja
sobrecarregado.
Preservar o estado de objetos entre os nós, mesmo em decorrência de falha dos
mesmos.
Utilizar mecanismos de comunicação entre os componentes do middleware que seja
assíncrono e funcione independentemente da dimensão atual da infraestrutura do
middleware.
Agendar e distribuir tarefas periódicas entre os vários nós distintos, independentes de
sua dimensão.
Requisitos
A partir dos objetivos mencionados na seção anterior, foram identificados os seguintes
requisitos para o eCaMid:
Gerenciar réplicas de nós: O eCaMid poderá adicionar vários nós à sua infraestrutura, onde existem várias réplicas de um mesmo nó. Cada réplica será identificada
individualmente e monitorada, para saber que réplicas estão ativas em um dado
instante;
Gerenciar estado de objetos remotos: o estado dos objetos remotos será compartilhado entre vários nós. O eCaMid deve prover um serviço que permita acessar o
estado a partir de qualquer nó;
Gerenciar ciclo de vida de objetos: objetos com estado devem ser gerenciados pelo
middleware. As estratégias de gerenciamento de ciclo de vida devem levar em conta
a distribuição do objeto em diferentes nós;
Efetuar comunicação Publish/Subscribe: componentes e objetos do eCaMid poderão trocar mensagens, onde emissores publicam mensagens que são recebidas pelos
receptores interessados;
Escalonar tarefas: Agentes podem ser usados para implementar ações periódicas,
que podem ser executadas para cada nó existente do middleware ou para todos os
nós; e
3.3. MODELO DE DOMÍNIO GERAL
49
Realizar balanceamento de carga: requisições encaminhadas para objetos remotos
devem ser distribuídas entre todos os nós existentes.
É possível identificar quatro atores que interagem com o eCaMid, a aplicação cliente,
a aplicação servidor, o provedor de nuvem e uma ou mais máquinas virtuais. A aplicação
cliente, que será mencionada apenas como cliente. O cliente conhece as interfaces dos objetos
publicados na parte servidor do eCaMid e realiza requisições remotas para esses objetos. A
aplicação servidor define os objetos remotos, subscribers e tarefas que serão gerenciados pelo
eCaMid. O Provedor de nuvem fornece uma API que é usada pelo componente Global Manager
para monitorar as máquinas virtuais existentes e os nós. As máquinas virtuais provêm o ambiente
em que processos do eCaMid serão executados. Cada máquina virtual identificada pelo provedor
de nuvem deverá possuir pelo menos um endereço de rede.
Três tipos possíveis de Stakeholders poderão utilizar o eCaMid, desenvolvedores de
aplicações, de middleware e provedores de nuvem. Desenvolvedores de aplicações distribuídas
utilizarão o modelo de programação oferecido pelo middleware para desenvolver soluções específicas para o ambiente de computação em nuvem. Desenvolvedores de middleware poderão
manter, atualizar as funcionalidades fornecidas pelo eCaMid e propor novas estensões. Provedores de nuvem poderão utilizar o eCaMid como blocos básicos para a criação de serviços de PaaS
sobre uma infraestrutura de IaaS.
O eCaMid também apresenta os seguintes requisitos não funcionais:
3.3
Independência de provedor de Infraestrutura de Nuvem: Os serviços funcionais
do eCaMid que suportam a elasticidade não devem depender de serviços fornecidos
por um provedor específico, seja este um provedor público ou privado;
Desempenho: O eCaMid deve fazer uso de todas as máquinas virtuais fornecidas
pelo provedor de nuvem com eficiência. O uso dos mecanismos de suporte à elasticidade do middleware devem utilizar os recursos da nuvem de forma mais eficiente;
Estrutura baseada em padrões de projeto: As soluções implementadas pelo
eCaMid devem fazer uso de vários padrões arquiteturais e de projeto presentes na literatura para resolver problemas já conhecidos, de forma a minimizar as complexidades
acidentais que são próprias de sistemas distribuídos.
Modelo de domínio geral
Nas duas últimas seções, pudemos identificar os objetivos e requisitos do middleware. No
entanto, para facilitar a compreensão da arquitetura do eCaMid, podemos ilustrar os elementos
que compõem o domínio do problema que o middleware pretende resolver, assim como os
relacionamentos entre esses elementos. A figura 3.1 ilustra o modelo inicial deste domínio, que
será explicado a seguir.
3.3. MODELO DE DOMÍNIO GERAL
50
Figura 3.1: Elementos básicos do modelo de domínio do eCaMid
O Provedor de Nuvem fornece uma API para gerência dos serviços de nuvem e um
conjunto de Máquinas Virtuais. As Máquinas Virtuais são identificadas unicamente para o
provedor de nuvem, e possuem um endereço IP único que pode ser alcançado pelo cliente. Um
processo do eCaMid que é executado sobre uma máquina virtual é chamado de Nó. Vários nós
compõem um conjunto chamado de Cluster, que por sua vez monitora as máquinas virtuais
fornecidas pelo provedor de nuvem através de sua API. Cada nó é identificado de forma única
no cluster.
Uma Aplicação é um conjunto de vários Componentes agrupados em uma unidade específica. A aplicação é implantada em um cluster, que por sua vez gerencia todos os componentes
da aplicação. Um componente é um objeto administrado pelo middleware, e pode ser realizado
como: uma Tarefa que é executada periodicamente; um Observer que trata eventos oriundos da
aplicação ou do próprio middleware; e um conjunto de Objetos Remotos. Todos os componentes
podem possuir objetos remotos como dependência, mas o mesmo não é possível com as outras
duas especializações. Um nó é responsável por executar a representação física de um componente
em algum instante onde este está sendo utilizado. Um Cliente localiza objetos remotos através
do cluster ou do próprio nó, e utiliza a invocação de métodos remotos para fazer requisições a
um objeto remoto.
Todos esses elementos, com exceção de Tarefa e Cluster já estavam presentes no middleware original MORAIS; LIBERALQUINO; ROSA (2013). Os elementos definidos nesta
seção constituem apenas os elementos mais básicos do modelo. Ao longo das próximas seções,
novos elementos serão introduzidos ao modelo, ao passo que as funcionalidades do eCaMid
serão detalhadas.
3.4. ARQUITETURA
3.4
51
Arquitetura
A Figura 3.2 representa os elementos que compõem o eCaMid. Da mesma forma que a
implementação inicial do CaMid, a arquitetura do eCaMid é dividida em três camadas: infraestrutura, distribuição e serviços. Alguns novos componentes e serviços foram adicionados à
arquitetura. Na camada de infraestrutura, foi adicionado o Group Communication Framework,
Cluster Request Handler e Group Channel. Na camada de distribuição, foram adicionados o
Cluster Event Bus, Task Scheduler, Invocation Router e Lifecycle Manager. Além dos componentes mencionados, foram adicionados os serviços Load Balancing Service e Storage Service
na camada de serviços. Os componentes Server Request Handler, Client Request Handler, Requestor, Invoker, Management Service e Naming Service já existiam na implementação original
(MORAIS; LIBERALQUINO; ROSA, 2013).
Figura 3.2: Visão geral dos componentes do eCaMid. Os elementos de cor branca
representam componentes, os de cor cinza representam serviços, enquanto o elemento
preto representa um framework. Os elementos em tracejado são oriundos da arquitetura
do CaMid, enquantos os elementos em linha contínua foram adicionados ao eCaMid.
O Group Communication Framework é o componente fundamental dos mecanimos de
coordenação e responsável por estabelecer um cluster, localizar e identificar membros (nós) e
prover mecanismos de comunicação multicast. O Group Channel e Cluster Request Handler
são dois componentes da camada de infraestrutura responsáveis por enviar e receber mensagens
3.4. ARQUITETURA
52
multicast. Os componentes Task Scheduler e Cluster Event Bus utilizam o Group Communication
Framework para prover serviços de coordenação em nível mais alto.
O componente Lifecycle Manager é responsável por controlar a criação e destruição de
objetos. Para isto, ele utiliza o Storage Service para armazenar os objetos remotos e um conjunto
de estratégias para gerenciar o estado dos objetos remotos. O Storage service, por sua vez, é uma
abstração para um sistema de armazenamento chave-valor que suporta controle de transação e
tratamento de eventos. É possível acessar o Storage Service a partir de qualquer um dos nós do
middleware. O componentes Lifecycle Manager e Storage Service constituem os mecanismos de
compartilhamento de estado utilizados pelo eCaMid.
O componente Invocation Router é utilizado na camada de distribuição para distribuir
requisições de objetos remotos aos diversos nós de um cluster. Este componente utiliza o Load
Balancing Service para definir como a carga de requisições será distribuída. O Load Balancing
Service é um componente que define uma série de políticas de balanceamento de carga. Esses
componentes utilizam as facilidades providas pelo framework de comunicação em grupo para
distribuir requisições recebidas dos clientes.
3.4.1
Coordenação
O eCaMid funciona como uma série de nós agrupados em uma entidade lógica denominada cluster. Este cluster precisa de meios eficientes para troca de mensagens entre nós,
utilizando diferentes estratégias de comunicação, como um-para-um, um-para-muitos e muitospara-um. Também precisa ter a capacidade para verificar que membros estão ativos, quando
um novo nó é adicionado ou quando um nó deixa o grupo, com a capacidade de executar ações
específicas quando algum desses eventos acontece. O gerenciamento de membros do eCaMid é
realizado através da utilização do framework de comunicação em grupo.
Este framework utiliza o padrão de projeto Object Group (MAFFEIS et al., 1996), mas ao
invés de gerenciar réplicas de objetos remotos, este gerencia nós de um cluster. Cada membro do
cluster recebe um identificador. O conjunto de todos os membros ativos do cluster compõem uma
View. Quando algum membro entra ou sai do grupo, uma nova View é gerada. O framework de
comunicação em grupo provê uma série de gatilhos para execução de ações quando determinados
eventos ocorrem no cluster, como a geração de uma view ou a falha de comunicação de um dos
membros do nó.
Algumas ações precisam ser executadas de forma única em todo o cluster. O padrão
de projeto Leader Election (HOMER et al., 2014) define um processo que é utilizado para
determinar um líder, o membro do cluster que realizará uma determinada tarefa em favor de
todos os outros membros. O eCaMid utiliza o evento de aquisição da view para executar uma
ação de atribuição de papéis específicos a cada nó.
Um desses papéis é chamado de coordenador, um papel atribuído pelo próprio framework
de comunicação em grupo. O coordenador é o membro mais antigo do cluster e é responsável
3.4. ARQUITETURA
53
por executar tarefas específicas para o próprio framework. Os demais membros do cluster são
chamados workers e são responsáveis por receber chamadas de método remotas. Um outro
papel definido é o Task Executor, que define um nó responsável por gerenciar os agentes que
executarão tarefas periódicas no cluster.
Além dos mecanismos de gerência de grupo, o eCaMid possui dois componentes que
oferecem uma infraestrutura alternativa que pode ser usada para comunicação intra-cluster.
Enquanto o Client Request Handler e Server Request Handler são usados na comunicação
cliente-servidor, o Group Channel é usado para enviar mensagens a outros membros do grupo,
utilizando o identificador do nó ao invés do endereço de rede.
O Group Channel suporta o estilo de comunicação unicast (um para um, com semântica
request-reply) e multicast (um para muitos, com semântica fire-and-forget). O Cluster Request
Handler é o componente de infraestrutura que recebe mensagens do Group Channel e as
encaminha para outros componentes da camada de distribuição, como o Invoker e Cluster
Event Bus. O Group Communication Framework age como um intermediário entre esses dois
componentes. A Figura 3.3 ilustra este estilo de comunicação.
Figura 3.3: Estilos de comunicação um-para-um e um-para-muitos
3.4.1.1
Comunicação Publish/subscribe
Os componentes Group Channel e Cluster Request Handler são dois componentes
fundamentais para a execução de tarefas assíncronas no eCaMid. No entanto, ambos são
componentes de baixo nível. Os componentes da camada de serviço e a aplicação necessitam de
um modelo de programação mais abstrato.
Uma forma de implementar a comunicação assíncrona entre os diversos componentes é
através da troca de mensagens. Utilizando um modelo Publish/subscribe, um publisher pode
enviar uma mensagem específica sem saber ao certo o destinatário. As mensagens são entregues
a todos os subscribers interessados na mesma. A Figura 3.4 mostra os elementos de domínio
3.4. ARQUITETURA
54
deste subsistema.
Figura 3.4: Modelo de domínio do subsistema de publish-subscribe
No escopo do eCaMid, as mensagens trocadas entre componentes são chamadas de
eventos. Eventos podem ter três naturezas: locais, onde o evento publicado por um publisher é
entregue para todos subscribers no mesmo nó; eventos de broadcast, onde o evento publicado em
um publisher é destinado aos subscribers em todos os nós do middleware; e eventos de cluster,
onde o publisher em um nó publica uma mensagem que deve ser entregue a todos os publishers
localizados em um dos nós membros do cluster, de forma a balancear a entrega de requisições
entre nós.
O componente responsável por publicar os eventos e encaminhar aos subscribers interessados chama-se Cluster Event Bus. Este componente é composto de duas partes: o Message
Router, responsável por enviar e receber mensagens para os destinatários locais e remotos,
encapsulando as chamadas ao Group Channel e o Cluster Request Handler; o Local Event Bus é
responsável por entregar os eventos recebidos a todos os subscribers localizados neste nó.
A principal finalidade do mecanimso de comunicação Publish-Subscribe é prover um
modelo de comunicação para os componentes de monitoramento do eCaMid, pertencentes ao
Local Manager e Global Manager que se comuniquem de forma fracamente acoplada e sem
contenção de recursos. No entanto, esses mecanismos também estão disponíveis para aplicações
que utilizem o eCaMid que desejem utilizar um mecanismo de comunicação assíncrona mais
simples, sem todas as garantias e complexidades de um middleware orientado a mensagens.
3.4.1.2
Escalonamento de tarefas periódicas
O eCaMid e a aplicação podem necessitar de uma infraestrutura para executar tarefas
periódicas. A coordenação e execução dessas tarefas é responsabilidade do componente Task
3.4. ARQUITETURA
55
Figura 3.5: Modelo de domínio do subsistema de escalonamento de tarefas
Scheduler. O modelo de domínio para o subsistema de escalonamento de processos é mostrado
na Figura 3.5.
As tarefas periódicas podem ser classificadas como tarefas locais e tarefas de cluster.
Tarefas locais são executadas no contexto de execução de cada um dos nós, enquanto tarefas de
cluster são executadas em um nó específico em prol de todo o cluster. Como exemplo de tarefas
periódicas locais, temos o processo de extração das métricas de uso de CPU e memória que é
executada em cada nó pelo Local Manager. Como exemplo de tarefa de cluster, temos um dos
agentes do Cluster Manager que solicita periodicamente do provedor de nuvem o status de todas
as máquinas virtuais usadas pelo middleware.
O componente Task Scheduler está presente em todos os nós e pode executar qualquer
tipo de tarefa periódica. O Task Scheduler recebe eventos relacionados à criação de uma view a
partir do Task Coordination Observer. O evento de criação de view informa para o Task Scheduler
quais os membros atuais do cluster. Caso o Task Scheduler atual seja o coordenador da view,
este será o responsável por executar as tarefas periódicas do cluster. Caso contrário, apenas as
tarefas locais são executadas. O Task Scheduler também responde a eventos de desligamento do
nó, interrompendo a execução de tarefas locais e de cluster de maneira graciosa.
3.4.2
Compartilhamento de Estado
Todos os nós em um cluster do eCaMid são réplicas idênticas uns dos outros, de forma a
manter a aplicação que reside sobre o middleware tolerante a falhas. Todos os componentes da
camada de serviços, como o Local Manager, o Global Manager e Naming Service estão presentes
em todos os nós, embora sejam executados apenas nos nós que possuem essa responsabilidade.
A maioria dos componentes da camada de serviços necessita armazenar dados, como a tabela de
Lookup presente no serviço de nomes. No entanto, esses dados não podem estar armazenados
apenas na memória de um nó, pois em caso de falha do mesmo, o cluster perderá esses dados.
3.4. ARQUITETURA
56
Por esse motivo, o eCaMid provê o Storage Service, uma abstração para um repositório
chave-valor cujos dados armazenados são compartilhados por todos os nós de um cluster, onde
cada nó acessa o Storage Service como se este fosse um componente local. Este repositório
tem suporte à expiração de dados e controle de transações para garantir a atomicidade das
operações realizadas. Várias estratégias de concorrência podem ser utilizadas no eCaMid, como
concorrência eventual, locking otimista e locking pessimista. O Storage Service pode ser utilizado
pela aplicação como um repositório de dados ou como cache de outras fontes de dados.
O Storage Service não faz uso do sistema de armazenamento chave-valor fornecido
pela nuvem, uma vez que nem todos os provedores dispõem deste serviço, como é o caso das
infraestruturas privadas OpenNebula e CloudStack. Ao invés disso, o Storage Service utilizado
no eCaMid funciona como um cache distribuído, onde cada nó do cluster conta como uma
partição deste sistema de armazenamento.
Os mecanismos de comunicação peer-to-peer utilizados pelo Storage Service são transparentes aos componentes do middleware, que utilizam de forma similar a um sistema de
armazenamento local. Cada vez que um determinado valor é armazenado no Storage Service,
esta entrada na tabela de armazenamento é replicada para outros N nós, onde N é determinado
pela configuração do middleware e é igual ou menor que a quantidade de nós presentes em um
Cluster. Quando um nó é adicionado ou removido, o Storage Service redistribui as entradas e
valores armazenados entre os nós presentes.
3.4.2.1
Gerenciamento de ciclo de vida de objetos remotos
Objetos são a principal abstração usada pelo eCaMid. Objetos podem depender de outros
objetos e cada um deles pode ser stateful ou stateless. Eles podem ser acessados localmente, no
mesmo processo em que está sendo executado ou através de chamadas de método remotas.
O acesso a estes objetos, sejam locais, distribuídos, stateless ou stateful, deve ser transparente. Para garantir esta forma de transparência, objetos remotos precisam ser gerenciados
pelo eCaMid, que controla como esses objetos são alocados, descartados ou acessados de forma
consistente por todos os nós de um cluster.
A Figura 3.6 ilustra o modelo de domínio para o subsistema de gerenciamento de ciclo
de vida do eCaMid.
O componente Lifecycle Manager é responsável por gerenciar o ciclo de vida dos objetos
remotos do eCaMid. Para isto, são implementadas as estratégias Per-Request Instance e ClientDependent Instance para definir de que forma o estado desses objetos será preservado. Ao
utilizar um objeto remoto que usa a estratégia Per-Request Instance, um novo objeto será criado
a cada requisição recebida de um cliente.
Objetos remotos que possuem estado utilizam a estratégia Client-Dependent Instance,
que consiste em manter o estado do objeto enquanto o cliente mantém uma conexão ativa com o
eCaMid. Uma conexão ativa é chamada de Sessão, que é identificada através de um UUID. O
Lifecycle Manager utiliza o UUID para guardar um objeto que representa a sessão de um cliente
3.4. ARQUITETURA
57
Figura 3.6: Modelo de domínio do subsistema de gerenciamento de ciclo de vida
através do Storage Service. Juntamente com o objeto de sessão, é guardado o estado de todos os
objetos remotos cujo escopo está atrelado à sessão. Os objetos de sessão são armazenados no
Storage Service pelo Lifecycle Manager.
O Lifecycle Manager utiliza um mecanismo de Leasing para gerenciar a alocação de
recursos de sessão. É definido um tempo de expiração (leasing) para todos os objetos de sessão
armazenados. Caso este objeto de sessão não seja acessado por um tempo superior ao tempo
de expiração, o Storage Service descarta o objeto de sessão, liberando os recursos que foram
alocados.
A resiliência do estado dos objetos é garantida pelo Storage Service, onde cada objeto
de sessão é armazenada como uma entrada na tabela chave-valor e replicado para os outros nós.
Existe a garantia de que o estado de um objeto esteja disponível no Cluster desde que no máximo
N-1 nós falhem abruptamente, onde N é o número de nós onde cada entrada chave-valor, sem a
chance de que o Storage Service consiga sincronizar esses objetos para os demais nós.
Uma estratégia de consistência eventual é utilizada para manter o estado do objeto de
sessão consistente sobre todos os demais nós. Caso o objeto seja acessado concorrentemente
em múltiplos nós e seu estado seja alterado, o último valor a ser atualizado será armazenado no
Storage Service. O problema de se utilizar mecanismos mais eficazes de controle de concorrência
é que esses mecanismos tendem a dificultar a escalabilidade da aplicação quando existe uma
grande quantidade de nós disputando os mesmos recursos. No entanto, o risco de acessar ClientDependent Instances inconsistentes é pequeno, visto que apenas um cliente em dado momento
pode realmente acessar este objeto. Caso, o mesmo cliente faça uma atualização dos objetos em
dois nós diferentes simultaneamente, a última atualização ao estado do objeto irá sobrescrever a
entrada existente na tabela de armazenamento.
Por esse motivo, o eCaMid não suporta a estratégia Static Instance, visto que o nível
de concorrência ao estado deste tipo de objeto poderia limitar de forma severa a escalabilidade
do middleware, ou impedir que este mantivesse um estado consistente. Portanto, componentes
3.4. ARQUITETURA
58
Figura 3.7: Componentes envolvidos na criação de objetos de sessão.
do middleware que precisam guardar estado (como Naming Service, Global Manager e Local
Manager) utilizam o Storage Service diretamente.
A Figura 3.7 mostra os elementos envolvidos durante a criação de um proxy que será
usado para acessar um objeto remoto. O cliente, quando deseja acessar um objeto remoto (seja
este stateless ou stateful), utiliza o Session Factory para iniciar uma conexão com o eCaMid. O
Session Factory solicita a criação de uma sessão para o Naming Service, que gera um UUID, e
publica uma mensagem de criação de sessão através do Cluster Event Bus. Este componente
notifica o Lifecycle Manager de um nó específico do evento de criação da sessão, que por sua
vez cria o objeto que representa a sessão, posteriormente o armazenando no Storage Service.
O Session Factory cria um objeto chamado SessionHandler, que representa a sessão
criada pelo cliente. Este session handler é uma representação da conexão criada pelo cliente para
o cluster. O Session Handler também é responsável por localizar objetos remotos e criar Proxies
que representam essas instâncias. Os Proxies são usados pelo cliente para realizar chamadas
remotas de método.
A Figura 3.8 ilustra os elementos envolvidos na invocação de métodos remotos. Quando
o cliente invoca um método em um Proxy, este constrói uma mensagem chamada de Method
Request Message. Esta mensagem é entregue ao Requestor, que insere outros cabeçalhos na
mensagem, obtém o endereço de rede do nó que possui a instância do objeto e por fim envia a
mensagem através de componentes de infraestrutura. O Invoker recebe uma Method Request
Message, extrai o identificador da sessão e solicita a criação de um objeto remoto ao Lifecycle
Manager. Caso o objeto remoto possua estado, este será criado utilizando o estado armazenado
na sessão.
3.4. ARQUITETURA
59
Figura 3.8: Componentes envolvidos em uma requisição de método remota.
O modelo de domínio inicial do eCaMid, apresentado na Figura 3.1, mostra que todos
os componentes do eCaMid podem acessar objetos remotos. No entanto, apenas objetos que
utilizam a estratégia Per-Request Instance podem ser referenciados por Observers e Tarefas,
visto que a informação de sessão não está presente em operações assíncronas.
3.4.3
Balanceamento de Carga
Para fazer uso dos recursos do cluster de forma eficiente, o eCaMid fornece um mecanismo de balanceamento de carga, que é adaptado ao modelo de comunicação característico dos
sistemas de middleware orientados a objeto.
Durante o processo de criação de uma View, alguns dos nós do tipo worker são escolhidos
para atuar como Routers, nós que encaminham requisições para outros nós, incluindo eles
mesmos. Os Routers são selecionados utilizando um algoritmo de Leader Election, escolhidos
a partir dos nós mais antigos do cluster, considerando algumas restrições: um nó não pode ser
coordenador e router ao mesmo tempo, a não ser que só exista um único nó em todo o cluster; a
quantidade de routers no cluster deve respeitar a proporção de 1 router para cada N workers,
onde o valor padrão de N é igual a 5. Essas restrições são utilizadas para evitar que os nós
utilizados como routers se tornem pontos únicos de falha, e não se tornem gargalos a medida
que o cluster aumenta de tamanho. Em caso de adição ou indisponibilidade de um nó, um novo
evento de criação da View é disparado, e o Load Balancing Service seleciona novamente os nós
que exercerão o papel de routers.
A Figura 3.9 ilustra os componentes envolvidos pelos mecanismos de balanceamento
3.4. ARQUITETURA
60
Figura 3.9: Componentes envolvidos em balanceamento de carga
de carga. O componente Load Balancing Observer contém vários callbacks que verificam a
chegada de eventos do framework de comunicação em grupo. O Load Balancing Service contém
heurísticas para realizar a escolha dos nós que terão o papel de routers e utiliza o Storage Service
para registrar essa informação. O Naming Service consulta o Load Balancing Service para obter
a localização dos routers. Um subcomponente do Load Balancing Service é chamado de Load
Balancing Strategy e consiste em uma heurística de balanceamento de carga.
Uma parte importante do subsistema de balanceamento de carga se refere ao roteamento
de requisições, que pode ser observado a partir da figura 3.10. Method Request Messages podem
ser de dois tipos: Direct Request, destinadas a um objeto remoto específico; e requisições de
grupo, destinadas a um grupo de objetos.
Figura 3.10: Componentes envolvidos em roteamento de requisições
O Invocation Router é um componente existente na camada de distribuição que é responsável por distribuir Method Request Messages para os demais nós de um cluster eCaMid. Ele
recebe Method Request Messages a partir do Server Request Handler. Caso sejam requisições
3.4. ARQUITETURA
61
diretas, este encaminha para o Invoker; caso contrário, utiliza o Load Balancing Strategy para
localizar o nó a quem deve ser entregue a mensagem do tipo Group Request. Quando possui essa
localização, o Invocation Router a encaminha para um nó remoto através do Group Channel.
Várias implementações de Load Balancing Strategy podem existir, para diferentes algoritmos
de balanceamento de carga. O eCaMid, nativamente, implementa os algoritmos Round-Robin e
Random-Robin.
O processo de comunicação entre cliente e servidor através do eCaMid é similar ao
processo existente em um middleware orientado a objeto tradicional. A Figura 3.11 ilustra um
diagrama de sequência com todos os passos necessários para realizar a comunicação Cliente/servidor utilizando os mecanismos de balanceamento de carga providos pelo eCaMid. Vários
componentes foram omitidos do diagrama, de forma a simplificar o entendimento:
Figura 3.11: Balanceamento de carga no eCaMid
1. Cliente solicita ao Naming Service a referência a um grupo de objeto remoto (1);
2. Naming Service consulta o Load Balancing Service para obter a localização de um
router, utilizando essa informação para construir um AOR e retorná-lo ao cliente
(1.1);
3. Cliente recebe o AOR do Naming Service, constrói um Proxy e o utiliza-o para
realizar chamadas de método remotos (2);
4. Ao receber a chamada de método, o Invocation Router consulta o Load Balancing
Strategy para saber a que nó deverá encaminhar a requisição (2.1);
3.5. TECNOLOGIAS UTILIZADAS
62
5. Se o nó for o mesmo que do Invocation Router, este encaminha a Method Request
Message para o Invoker e recebe a resposta da invocação remota (2.2). Caso contrário,
o Invocation Router utiliza o Group Channel como intermediário para enviar o
Method Request Message ao nó destino (2.3); e
6. Invoker responde a requisição que, por sua vez, é encaminhada de volta para o
Invocation Router. O Invocation Router encaminha a resposta recebida ao cliente
que iniciou a chamada remota (2.3.1).
O Invocation Router pode falhar, devido a uma indisponibilidade ou desligamento do nó.
Neste caso, a parte cliente do middleware deve tratar essa falha de forma transparente, refazendo
uma consulta ao serviço de nomes. O processo descrito na Figura 3.12 ilustra essa situação:
Figura 3.12: Tolerância a falhas no mecanismo de balanceamento de carga.
1. O cliente realiza uma chamada remota a um nó específico. Por estar indisponível, o
cliente recebe uma falha de conexão, que é tratada de forma transparente pelo cliente
(1);
2. Os componentes da porção cliente do middleware realizam uma consulta ao serviço
de nomes, obtendo uma nova referência para o nó em que o objeto remoto encontra-se
localizado (2);
3. O cliente realiza uma requisição ao novo nó, e recebe a resposta da invocação remota
(3).
É importante observar que alguns componentes foram omitidos do diagrama para simplificar a explicação do processo.
3.5
Tecnologias utilizadas
A implementação do eCaMid depende de várias tecnologias para implementar as suas
funcionalidades.
3.5. TECNOLOGIAS UTILIZADAS
63
O framework de comunicação em grupo utilizado pelo eCaMid chama-se JGroups. Os
componentes Group Channel e o Cluster Request Handler são duas abstrações criadas pelo
eCaMid com a finalidade enviar e receber mensagens em um ambiente intra-cluster.
A implementação atual do Storage Service utiliza a tecnologia Infinispan (MARCHIONI,
2012) para criar vários repositórios chave-valor distribuídos com finalidades específicas. O
Storage Service define um repositório para cada serviço específico do eCaMid. Cada repositório
possui configurações específicas: os repositórios do Local Manager e Global Manager utilizam
um repositório chave-valor básico; os repositórios do Naming Service e Load Balancing Service
são otimizados para leitura de informações, portanto, utilizam um cache L1 provido pelo
Infinispan para conservar os dados mais requisitados na memória de cada nó; o repositório
utilizado pelo Lifecycle Manager é configurado para descartar os valores armazenados após
um tempo de expiração definido, além de utilizar um gerenciador de transações para garantir a
consistência da atualização do estado de objetos remotos que é acessado em diversos nós de um
cluster.
Para fazer a "cola"de seus vários subsistemas, o eCaMid usa em seu núcleo um framework
de injeção de dependências chamado Guice (VANBRABANT, 2008). Esta tecnologia fornece
um container que é responsável pela criação de cada objeto utilizado no eCaMid e de cada uma
de suas dependências. Todos os componentes internos do eCaMid são objetos gerenciados pelo
Guice. Os componentes do eCaMid estão agrupados na forma de módulos: existe um módulo
com as funcionalidades principais, como invocação de métodos remotos, gerenciamento de ciclo
de vida e a API de storage; um módulo com a implementação do Storage Service; um módulo
com as funcionalidades de coordenação e clustering, utilizando o JGroups; um módulo com
os mecanismos de balanceamento de carga usados no eCaMid; e por fim, um módulo com os
serviços de gerenciamento, o Local Manager e Global Manager.
A aplicação que usa o eCaMid também utiliza o mecanismo de módulos do Guice para
definir quais componentes irão compor a aplicação. O eCaMid provê uma API específica para
configuração de um módulo de uma aplicação, permitindo que este defina todos os objetos
remotos, a estratégia de ciclo de vida de cada um deles, um conjunto de subscribers e tarefas
periódicas. O Lifecycle Manager fornece um conjunto de extensões ao Guice que permite
a utilização das estratégias de ciclo de vida de middleware (Per Request Instance e Client
Dependent Instance) através dos mecanismos de injeção de dependência.
O Guice também permite a utilização de interceptadores e programação orientada a
aspectos, permitindo a criação de comportamentos secundários que podem ser aplicados em
diferentes contextos da aplicação. Os coletores de métricas de QoS utilizados no eCaMid
utilizam interceptadores em métodos específicos dos componentes Server Request Handler e
Invoker para calcular o tempo de resposta e o número de vezes que determinado método foi
invocado. Adicionalmente, os interceptadores fornecidos pelo Guice poderiam ser usados para
implementar mecanismos de segurança e controle de transação.
3.6. IMPLANTAÇÃO
64
Figura 3.13: Diagrama de implantação para nós do eCaMid
3.6
Implantação
O eCaMid é distribuído como uma biblioteca. O desenvolvedor da aplicação precisa
desenvolver um módulo, onde declara quais são os objetos remotos, tarefas de background e subscribers que serão gerenciados pelo middleware. Um componente chamado eCaMidClusterServer
é utilizado para incluir todos os módulos definidos pela aplicação e para iniciar a execução do
middleware. A Figura 3.13 ilustra a arquitetura de implantação do eCaMid.
Cada nó individual precisa, de alguma forma, descobrir os seus vizinhos e iniciar um
cluster, uma etapa conhecida como bootstrapping. A estratégia utilizada pelo eCaMid é definir
pelo menos um nó encarregado de centralizar os mecanismos de descoberta dos demais nós. O
endereço de rede utilizado por ambas as máquinas virtuais deve ser conhecido previamente. Os
nós executados sobre as duas máquinas virtuais devem ser executados em modo de administrador
do cluster e os endereços de ambas as máquinas virtuais devem ser passadas como parâmetro.
Os dois nós mencionados podem ser categorizados como nós fixos, e são utilizados pelos
demais nós para localizar os outros membros do cluster. Foram escolhidos a presença de dois
nós, para que o primeiro atue como nó principal e o segundo como failover. Contudo, qualquer
número de nós fixos pode ser usado, e o uso de mais de um nó fixo existe para garantir um
mecanismo de failover, evitando um ponto central de falha. Caso algum dos nós fixos falhe, é
recomendado que o usuário o reinicie com exatamente as mesmas configurações, como endereço
IP, para que o cluster não perca a capacidade de bootstrapping.
O demais nós do eCaMid são chamados de nós elásticos e podem ser ativados a qualquer
3.7. CONSIDERAÇÕES FINAIS
65
momento pelo usuário. Cada nó elástico precisa saber a localização dos dois nós fixos para
então descobrir a localização dos demais membros do cluster. À medida que novos nós elásticos
são adicionados à infraestrutura do middleware pelo usuário de nuvem, os novos membros
utilizarão uma configuração inicial para localizar os nós fixos e serão adicionados ao cluster
dinamicamente.
O cliente do eCaMid está implantado em uma máquina virtual separada. Para realizar a
ação de bootstrapping, o cliente precisa saber o endereço de rede de um nó fixo para então acessar
o serviço de nomes que está implantado em ambos. A partir do serviço de nomes, o cliente
obterá a localização de um dos routers, que será o intermediário do cliente para a realização de
requisições remotas.
3.7
Considerações Finais
Neste capítulo, foram apresentados os objetivos e requisitos da arquitetura do eCaMid.
Em seguida, foram explicados todos os mecanismos adicionados à arquitetura do CaMid original: coordenação, comunicação assíncrona, execução de tarefas, compartilhamento de estado,
gerência de ciclo de vida e balanceamento de carga. Nas demais seções foram explicadas as
tecnologias utilizadas pelo eCaMid para prover seus serviços e uma arquitetura de implantação
para o mesmo.
66
4
Avaliação de Desempenho e Discussão
No capítulo anterior, foram apresentados vários mecanismos que estendem as funcionalidades fornecidas pelo CaMid original, de forma a suportar o desenvolvimento de aplicações
elásticas na nuvem. No entanto, a arquitetura e os mecanismos apresentados precisam ser validados, para que seja possível quantificar os benefícios de desempenho e escalabilidade trazidos
pelas novas funcionalidades.
Neste capítulo, iremos apresentar uma avaliação experimental que foi realizada com o
eCaMid. Iniciaremos este capítulo citando os objetivos da avaliação e a metodologia utilizada.
Em seguida, serão mostrados os resultados obtidos a partir da avaliação e será realizada uma
análise dos benefícios e prejuízos dos novos mecanismos do eCaMid nos cenários avaliados.
4.1
Objetivos e Metodologia
A avaliação experimental usada no eCaMid utiliza a metodologia sistemática definida
por JAIN (1991), voltada para avaliação de desempenho. O experimento realizado no eCaMid
visa provar que os mecanismos de coordenação, replicação e balanceamento de carga não
causam a queda de desempenho da aplicação. É necessário também provar que o mecanismo
de balanceamento de carga utilizado consegue preservar o desempenho da aplicação quando
nós são adicionados dinamicamente em um cluster, provando que seus mecanismos internos são
capazes de reagir a mudanças de topologia rapidamente.
Para implementar a avaliação foi desenvolvida uma aplicação simples, que foi desenvolvida utilizando o modelo de programação do eCaMid. Esta aplicação é constituída de um objeto
remoto chamado PasswordEncryptionService que contém um método que aplica um hashing
criptográfico a uma senha, utilizando o algoritmo PBKDF2WithHmacSha1, com um salt de 64
bits e uma senha de 160 bits. Este algoritmo aplica várias funções de hash à senha utilizada
iterativamente, com o objetivo de aumentar o tempo necessário para realizar um ataque de força
bruta que visa descobrir a senha original a partir do hash gerado. O objetivo desta aplicação é
prover um kernel possa executar uma operação que é exigente em termos de processamento (uso
de CPU), é comum em aplicações de nuvem (hashing criptográfico de senha) e não depende de
4.1. OBJETIVOS E METODOLOGIA
67
um mecanismo de persistência durável, como é o caso de um banco de dados.
Duas versões do mesmo objeto foram construídas. Na versão stateless, um salt é gerado
a cada vez que um método é chamado e é aplicado o hashing criptográfico à senha utilizando
este salt e o número de iterações do algoritmo. Na versão stateful, o salt é criado apenas na
construção do objeto, permanecendo na memória mesmo a cada execução.
Dois diferentes cenários foram utilizados para fazer a avaliação experimental do eCaMid.
O primeiro consiste no uso de uma máquina virtual representando a aplicação cliente e uma
aplicação servidor com um conjunto de objetos remotos, o serviço de nomes e o global manager,
que é executada em uma segunda máquina virtual. Neste primeiro cenário, o middleware é
executado sem os mecanismos de suporte à elasticidade fornecidos pelo eCaMid, visando criar
um ambiente similar ao utilizado na avaliação experimental do CaMid original.
O segundo cenário é bastante similar ao primeiro, com uma máquina virtual contendo o
cliente e a outra com a parte servidor. Neste caso, no entanto, os mecanismos de coordenação,
compartilhamento de estado e balanceamento de carga foram ativados. Adicionalemente, novos
nós seriam adicionados ao cluster em intervalos regulares, através de um script, cada um
executado uma nova máquina virtual. Apenas um nó fixo será utilizado, sem a utilização de
failover, visto que esta avaliação não procura avaliar os mecanismos de disponibilidade do
middleware. Este cenário visa criar um ambiente onde são utilizados os recursos de elasticidade
do eCaMid, incluindo a sua capacidade de adaptação ao redimensinamento da infraestrutura.
4.1.1
Métricas, Parâmetros e Fatores
As métricas utilizadas para avaliar o desempenho do eCaMid são tempo de resposta e
vazão. As métricas tempo de resposta e vazão visam medir o desempenho e escalabilidade do
sistema.
A fórmula usada para medir o tempo de resposta é: Tresposta = t f im − tinicio , onde t f im
representa o instante em que a requisição foi concluída com sucesso e tinicio representa o instante
em que a requisição foi iniciada. Para o cálculo do tempo de resposta, apenas as requisições que
completaram com sucesso são contabilizadas.
A fórmula usada para calcular a vazão é: V = Rsucesso
, onde Rsucesso representa o número
T
de requisições completadas com sucesso e T representa um intervalo temporal específico.
A métrica de tempo de resposta é calculada para cada requisição realizada durante a
avaliação. Já a métrica de vazão é calculadas uma vez ao final da avaliação, utilizando o número
de requisições para um intervalo específico.
Uma série de parâmetros podem afetar as métricas mencionadas: (1) Número total de
clientes concorrentes em um intervalo X; (2) O número total de iterações utilizado pelo algoritmo
PBKDF2WithHmacSha1; (3) Tamanho do salt utilizado; (4) Tamanho do hash gerado; (5) Taxa
de transferência da rede; (6) Capacidade de processamento da máquina virtual; (7) Quantidade
de servidores virtuais; (8) Estado de objeto remoto.
4.1. OBJETIVOS E METODOLOGIA
68
As aplicações, em ambos os cenários, devem ter a escalabilidade suficiente para atender
um grande número de requisições simultâneas. O número de clientes que realizam requisições
influenciam diretamente as métricas de tempo de resposta e vazão. O tempo de resposta do
sistema avaliado deve apresentar um valor baixo quando o número de clientes é pequeno, e deve
crescer à medida que o número de clientes aumenta. A vazão não apresenta o mesmo tipo de
variação. Caso o número de clientes seja baixo, a vazão deve apresentar um valor baixo. A vazão
do sistema aumenta com um número de clientes até alcançar um ponto de saturação. Após este
ponto, a vazão do sistema tende a cair. Este comportamento pode ser provado analiticamente
através da teoria das filas (BAKOUCH, 2011).
O número de iterações, dos parâmetros que afetam o mecanismo de hashing criptográfico,
possui a maior influência sobre as métrica de desempenho, pois este tem um impacto direto sobre
a complexidade computacional do algoritmo. Logo, se o número de iterações é grande, maior
será o tempo de resposta do sistema e menor a vazão. Pode ser fixado um tamanho de hash e salt
entre os valores recomendados enquanto são variados os valores de número de iterações para
aumentar ou diminuir o tempo de resposta (TURAN et al., 2010).
A taxa de transferência da rede pode influenciar diretamente o desempenho e escalabilidade do sistema avaliado. Por este motivo, para os dois cenários avaliados, é utilizado um
ambiente de rede homogêneo. A mesma estratégia é adotada para a capacidade de processamento,
utilizando máquinas virtuais com a mesma configuração em todos os cenários avaliados.
A quantidade de servidores virtuais usados na avaliação tem pouca influência no desempenho, mas grande influência na escalabilidade do sistema avaliado. No primeiro cenário, um
único servidor virtual é utilizado, enquanto no segundo cenário, é utilizado um único servidor
virtual e mais quatro servidores virtuais são adicionados através do script que executa o teste
de desempenho. Foi escolhido o número total de cinco servidores virtuais para que fosse possível observar o ganho incremental nas métricas ao se adicionar novos servidores virtuais na
infraestrutura.
Caso o objeto remoto apresentado pelo sistema testado possua estado durante a execução
do middleware, este pode afetar de maneira adversa o desempenho do sistema avaliado por
conta do esforço necessário para manter este estado consistente. Caso este mesmo objeto seja
utilizado concorrentemente, a sincronização dessas requisições adicionam um impacto sobre o
desempenho do middleware. Se este estado for compartilhado com outros nós, como é o caso do
segundo cenário, o custo de sincronização afetará diretamente o tempo de resposta e vazão da
aplicação.
Dentre os parâmetros citados, alguns foram escolhidos como fatores do experimento.
Foram escolhidos parâmetros que podem ser variados durante a geração da carga de trabalho
realizada no experimento e que são pertinentes para ambos os cenários. Os fatores escolhidos, e
seus respectivos valores são:
Número de clientes: Foram utilizados os valores 50, 100, 150 e 200 para a quantidade de clientes simultâneos. Estes valores são suficientes para testar a aplicação em
4.1. OBJETIVOS E METODOLOGIA
69
cenários diversos.
4.1.2
Número de iterações para o algoritmo PBKDF2WithHmacSha1: Foram selecionados os valores 8000, 16000, 32000 e 64000 iterações para o algoritmo de hashing
criptográfico.
Estado do objeto remoto: Este fator possui dois níveis: com estado (stateless) e
sem estado (stateful).
Técnica de avaliação, carga de trabalho e projeto de avaliação
Foi escolhida a técnica de experimentação para realizar a avaliação de desempenho do
eCaMid. Esta técnica permite testar um protótipo real do middleware, em uma situação que se
aproxima do uso real de uma aplicação distribuída.
O provedor de nuvem escolhido foi o AWS, onde o serviço Elastic Compute Cloud (EC2)
foi utilizado para provisionar as máquinas virtuais que foram usadas nos experimentos e fornecer
uma imagem que já continha uma instalação prévia do eCaMid e um script de inicialização.
As máquinas virtuais utilizadas em todos os experimentos e cenários eram da classe m1.small,
com 1.7 GB de memória RAM e 1 Compute Unit1 e localizadas na zona us-west-2a. Em cada
máquina virtual foi instalado o sistema operacional Ubuntu Server 64 bits 12.04.
Uma máquina virtual separada foi utilizada para simular os clientes do sistema avaliado.
Um programa sintético foi utilizado para simular os clientes, registrar o tempo de resposta de
cada requisição e registrar se esta foi terminada com sucesso ou não. Cada cliente é simulado
através de uma thread separada, onde cada cliente realiza uma nova requisição, com um intervalo
entre cada requisição. O valor deste intervalo é definido como uma variável aleatória distribuído
através de uma função gaussiana, com média de 300 ms e desvio padrão de 100 ms.
Cada experimento teve uma duração de 12 minutos, onde um minuto é utilizado como
tempo de espera para que o programa sintético seja carregado e estabilizado (warm-up). O
segundo minuto do experimento é utilizado para iniciar cada cliente em intervalos regulares
(ramp-up). Supondo que sejam 200 clientes usados no experimento, então um novo cliente é
iniciado a cada 30 segundos.
O programa sintético foi criado através da utilização da ferramenta JMeter (APACHE
JMETER, 2013). Foi criado um Sampler específico do JMeter que utiliza a parte cliente do
eCaMid para se comunicar com a parte servidor da aplicação, onde o cluster está desativado
no primeiro cenário e ativado no segundo. Através do JMeter foi possível implementar os
mecanismos de simulação de clientes, warm-up e ramp-up utilizados no experimento.
Os objetos remotos que contém a função de hashing criptográfico, podem ou não conter
estado. Na implementação stateless, um novo valor de salt é gerado para cada nova requisição
11
Compute Unit é equivalente a capacidade de processamento de um processador Opteron, com 1.0 GHz,
fabricado em 2007
4.2. RESULTADOS
70
do método de hashing, portanto, duas invocações para aplicação de hashing à mesma senha
irão produzir hashes diferentes. Na implementação stateful, o valor do salt é gerado durante
a invocação do primeiro método. Invocações susbsequentes para a mesma senha irão gerar o
mesmo hash. O valor retornado por objetos stateful é usado para verificar se houve algum erro
de consistência. Objetos stateless utilizam a estratégia Per-Request Instance, enquanto objetos
stateful Client-Dependent Instance.
Ao final de cada experimento, as máquinas virtuais foram reiniciadas e todos as partes
da aplicação, cliente ou servidor, foram reiniciados, para reduzir a possibilidade de saturação
dos recursos gerenciados pelo sistema operacional da máquina virtual e da própria aplicação. Os
experimentos foram conduzidos em horário comercial, para evitar algum problema relacionado à
manutenção da infraestrutura do provedor de nuvem.
4.2
Resultados
Foram realizados vários experimentos para avaliar todos os fatores e seus níveis em cada
cenário específico. Os experimentos foram divididos em grupos, que são nomeados de acordo
com o cenário e o tipo de objeto remoto utilizado. O cenário onde é utilizado apenas uma máquina
virtual cliente e outra máquina virtual servidor é chamado de "Direct", enquanto o experimento
onde novas máquinas virtuais são adicionadas é chamado de "Elastic-Clustered". Este nome é
seguido pelo tipo de objeto utilizado, ou seja, Stateless ou Stateful. Desta forma, temos ao todo,
quatro grupos de experimentos: Direct-Stateless, Direct-Stateful, Elastic-Clustered-Stateless e
Elastic-Clustered-Stateful.
4.2.1
Resultados individuais de cada experimento
O primeiro grupo de experimentos, Direct-Stateless, consiste no uso do primeiro cenário,
com apenas um único servidor virtual, sem o mecanismo de clustering ativo e um objeto remoto
stateless.
A Tabela 4.1 mostra os valores de tempo de resposta para o primeiro cenário (um cliente
e um único servidor), utilizando um objeto stateless. Podemos observar que o tempo de resposta
sofre grande influência do número de iterações e número de clientes. Fixando o número de
iterações e aumentando o número de clientes, podemos verificar um aumento proporcional no
tempo de resposta. Se fixarmos em 8000 iterações e comparando ao experimento com 50 clientes,
temos um aumento de 111,83% no tempo de resposta ao se utilizar 100 clientes, um aumento de
224,01% para 150 clientes e um aumento de 333,66% para 200 clientes. Ao fixar o número de
clientes e aumentar o número de iterações, o tempo de resposta também aumenta. Se fixarmos
em 200 clientes, e tomando como base de comparação o experimento com 8000 iterações, temos
um aumento no tempo de resposta de 93,40% para 16000 iterações (2x), 271,46% para 32000
iterações (4x) e 609,29% para 64000 iterações.
4.2. RESULTADOS
71
A vazão neste grupo de experimentos é bastante influenciada pelo número de iterações
do algoritmo, uma vez que ao fixar o número de clientes e aumentar o número de iterações,
é possível verificar uma queda no valor da vazão. Podemos tomar como base o experimento
realizado com 100 clientes e 8000 iterações. É possível notar uma queda de 47,59% na vazão ao
aumentar o número de iterações para 16000, 73,13% para 32000 iterações e 85,88% para 64000
iterações. Fixando o número de iterações e aumentando o número de clientes, não é possível
verificar uma mudança significativa no valor da vazão. Tomando como base o experimento
realizado com 16000 iterações e 50 clientes, temos: um aumento de 0,98% na vazão, para 100
clientes; um aumento de 1,50% para 150 clientes; e um aumento de 2,03% para 200 clientes.
Este comportamento revela que a vazão pode aumentar de acordo com o número de clientes,
mas logo alcança um ponto de saturação, uma vez que um único servidor não pode oferecer uma
vazão superior ao valor determinado.
Tabela 4.1: Tempo de resposta e vazão para o grupo de experimentos Direct-Stateless
Desvio
Tempo de
Padrão do Vazão
Número de Número de
Resposta
reqs
Iterações
Tempo
de ( s )
Clientes
Médio (ms)
Resposta
50
8000
1912.48
398.13
21.48
50
16000
3900.64
799.03
11.32
50
32000
7827.18
1595.72
5.85
50
64000
15766.51
3404.48
2.96
100
8000
4051.24
820.81
21.81
100
16000
7994.80
1636.08
11.43
100
32000
15841.15
3454.87
5.86
100
64000
30125.43
7554.98
3.08
150
8000
6196.63
1247.62
21.87
150
16000
12054.57
2538.94
11.49
150
32000
23489.23
5597.71
5.96
150
64000
44718.56
12588.79 3.16
200
8000
8293.75
1703.16
22.02
200
16000
16040.37
3564.74
11.55
200
32000
30808.19
7935.22
6.07
200
64000
58826.57
18205.86 3.21
O grupo de experimentos Direct-Stateful consiste em um conjunto de experimentos
realizados utilizando um único servidor virtual, onde um cliente faz chamadas a um objeto
remoto stateful. A Tabela 4.2 ilustra as métricas obtidas com a realização deste grupo de
experimentos. O tempo de resposta e vazão apresentam comportamento bastante similar àquele
verificado ao grupo de experimentos anterior. Fixando um número de iterações em 8000, o
tempo de resposta apresenta aumentos de 105,53% para 100 clientes, 215,21% para 150 clientes
e 323,76% para 200 clientes, quando comparados ao tempo de resposta do experimento que
utiliza apenas 50 clientes.
4.2. RESULTADOS
72
A vazão apresenta comportamento bastante similar ao primeiro experimento, onde
diminui à medida que o número de iterações aumenta, mas não apresenta diferença significativa
ao aumentar o número de clientes. Fixando o parâmetro de 8000 iterações e aumentando e
tomando como base o experimento com 50 clientes, é possível notar um aumento na vazão de
4,56% para 100 clientes, 4,52% para 150 clientes e 0% para 200 clientes.
No entanto, o contrário acontece ao aumentar o número de iterações do experimento. Ao
fixar o parâmetro de 50 clientes e usando o valor da vazão do experimento para o nível de 8000
iterações como referência, podemos notar uma redução de 45% na vazão ao se comparar com o
mesmo experimento utilizando 16000 iterações, 73% comparado ao experimento com 32000
iterações e finalmente redução de 85,58% se comparado ao experimento com 64000 iterações.
Os valores da vazão mostram que o desempenho do sistema é fortemente afetado pelo
número de iterações utilizados pelo algoritmo, mas a capacidade de servir requisições não se
altera conforme são aumentados o número de clientes para 100, 150 e 200.
Tabela 4.2: Tempo de resposta e vazão para o grupo de experimentos Direct-Stateful
Desvio
Tempo de
Número
de
Padrão do Vazão
Número de
Resposta
reqs
Iterações
Tempo de ( s )
Clientes
Médio (ms)
Resposta
50
8000
1997.32
683.69
20.59
50
16000
3920.87
740.21
11.26
50
32000
8272.07
1355.26
5.50
50
64000
15695.76
3036.36
2.97
100
8000
4105.07
681.57
21.53
100
16000
8275.17
1087.22
10.73
100
32000
15904.29
3152.28
5.84
100
64000
31440.58
4781.80
2.87
150
8000
6295.79
1007.08
21.52
150
16000
11978.64
1402.58
10.71
150
32000
23275.31
5065.11
5.89
150
64000
44999.69
11665.05 3.11
200
8000
8463.90
918.67
20.59
200
16000
16203.36
3153.84
11.43
200
32000
31837.73
4952.01
5.72
200
64000
58895.39
16956.20 3.17
O terceiro grupo de experimentos, Elastic-Clustered-Stateless, utiliza o segundo cenário
(um único servidor virtual, com novos nós adicionados em intervalos regulares de 2 minutos)
utilizando objetos stateless. Este grupo de experimento visa mostrar o aumento da vazão
resultantes do uso de clustering e balanceamento de carga, em uma infraestrutura dinâmica.
A Tabela 4.3 mostra os valores de tempo de resposta, vazão e proporção de erros obtidos
durante os experimentos. O tempo de resposta para este grupo de experimentos aumenta à medida
que o número de iterações e número de clientes é elevado. Fixando o número de clientes em 50
4.2. RESULTADOS
73
e utilizando como base o experimento em que o número de iterações é igual a 8000, podemos
afirmar que o tempo de resposta médio apresenta um aumento de 96,27% para 16000 iterações
do algoritmo, 328,92% para 32000 iterações e 673,67%, para 64000 iterações. Fixando-se o
número de iterações em 8000, e tomando como base o experimento realizado com 50 clientes,
podemos verificar que o tempo de resposta sofre um aumento de 154,91% para 100 clientes,
286% para 150 clientes e 441,57% para 200 clientes.
A vazão, assim como nos grupos de experimentos anteriores, apresenta uma queda,
conforme o número de iterações é elevado e mantém-se estável caso seja aumentado o número de
clientes. Tomando como base o experimento com 8000 iterações e 50 clientes, a vazão apresenta
uma redução de 4,67% ao elevar o número de clientes para 100, 1,01% para 150 clientes e 2,03%
para 200 clientes. Mantendo-se 50 clientes e tomando-se como base o valor do fator de 8000
iterações, a vazão apresenta redução de 39,64% ao aumentar o número de iterações para 16000,
69,61% para 32000 iterações e 82,46% para 64000 iterações. Da mesma forma que os demais
grupos de experimentos, a vazão apresentou pouca variação ao aumentar o número de clientes e
apresentou uma redução significativa ao aumentar o número de iterações do algoritmo.
Tabela 4.3: Tempo de resposta e vazão para o grupo de experimentos
Elastic-Clustered-Stateless
Desvio
Tempo de
Padrão do Vazão
Número de Número de
Resposta
reqs
Iterações
Tempo de ( s )
Clientes
Médio (ms)
Resposta
50
8000
692.73
1402.10
47.32
50
16000
1359.65
839.53
28.56
50
32000
2971.23
2473.77
14.38
50
64000
5359.47
2894.16
8.30
100
8000
1765.87
2026.29
45.11
100
16000
2996.27
1538.87
28.58
100
32000
6228.81
5546.95
14.19
100
64000
10687.89
4811.57
8.42
150
8000
2673.91
2464.86
46.84
150
16000
4859.51
3251.26
27.23
150
32000
8779.19
5783.85
15.33
150
64000
15964.65
6466.65
8.35
200
8000
3751.62
2528.46
46.36
200
16000
6442.87
4582.37
27.64
200
32000
12083.41
6798.01
14.73
200
64000
22564.70
11843.50 7.91
O último grupo de experimentos, Elastic-Clustered-Stateful, utiliza o mesmo cenário
que o grupo de experimento anterior, mas utilizando um objeto stateful. Os valores de tempo de
resposta e vazão para este grupo de experimentos podem ser encontrados na Tabela 4.4.
Da mesma forma que os demais grupos de experimentos, o tempo de resposta médio
tende a aumentar conforme o número de clientes ou o número de iterações aumenta. Utilizando
4.2. RESULTADOS
74
como referência o experimento com 50 clientes e 8000 iterações, podemos notar um aumento de
118,28% quando é elevado para 100 o número de clientes, 207,36% para 150 clientes e 313,77%
para 200 clientes. Com o mesmo experimento de referência, podemos notar um aumento de
93,40% quando o número de iterações é elevado para 100, 207,36% quando elevado para 150 e
313,77% quando elevado para 200 clientes. Esses aumentos percentuais mostram um aumento
aproximadamente proporcional no tempo de resposta médio em relação ao número de clientes.
A vazão neste grupo de experimentos também é fortemente influenciada pelo número de
iterações do algoritmo, mas pouca diferença em relação ao número de clientes. Tomando como
base o experimento com 50 clientes e 8000 iterações, podemos notar uma redução de 2,79% na
vazão quando o número de clientes é elevado para 100, um aumento de 6,79% quando elevado
para 150 clientes e um aumento de 6,84% para 200 clientes. Utilizando o mesmo experimento
como referência, a vazão sofre uma redução de 44,62% ao aumentar o número de iterações para
16000, 71,86% para 32000 iterações e 84,89% para 64000 iterações.
Tabela 4.4: Tempo de resposta e vazão para o grupo de experimentos
Elastic-Clustered-Stateful
Desvio
Tempo de
Padrão do Vazão
Número de Número de
Resposta
reqs
Iterações
Tempo de ( s )
Clientes
Médio (ms)
Resposta
50
8000
2095.47
671.43
19.72
50
16000
4052.72
665.77
10.92
50
32000
8231.49
1122.49
5.55
50
64000
15621.19
2988.64
2.98
100
8000
4574.11
850.11
19.17
100
16000
8322.15
1421.50
10.98
100
32000
15930.67
3150.86
5.83
100
64000
28666.47
4133.83
2.90
150
8000
6440.65
1027.45
21.06
150
16000
12957.76
1410.84
10.55
150
32000
23718.77
5258.13
5.87
150
64000
36216.29
5351.00
2.89
200
8000
8670.54
1430.04
21.07
200
16000
16480.27
3196.92
11.24
200
32000
28915.12
4386.49
5.68
200
64000
37511.40
8177.64
3.01
4.2.2
Comparação entre resultados
A Figura 4.1 mostra uma série de gráficos de barra que demonstram a diferença entre os
valores de tempo de resposta, comparando o número de clientes e o grupo de experimento, para
cada valor específico do número de iterações. É possível observar através de todos os gráficos
que o tempo de resposta médio do grupo de experimentos Elastic-Clustered-Stateless apresenta
4.2. RESULTADOS
75
o menor valor, comparado aos demias grupos de experimento.
O tempo de resposta para os grupos de experimentos Elastic-Clustered-Stateful, DirectStateless e Direct-Stateful apresentam valores similiares nas Figuras 4.1a e 4.1b. No entanto,
para níveis maiores do fator número de iterações, podemos observar que o tempo de resposta
médio do grupo de experimento Elastic-Clustered-Stateful tende a ser menor quando comparado
aos grupos de experimento Direct-Stateless e Direct-Stateful.
(a) Tempos de resposta vs número de clientes com (b) Tempos de resposta vs número de clientes com
número de iterações igual a 8000
número de iterações igual a 16000
(c) Tempos de resposta vs número de clientes com (d) Tempos de resposta vs número de clientes com
número de iterações igual a 32000
número de iterações igual a 64000
Figura 4.1: Gráficos de barra para comparação de tempo de resposta médio entre todos
os grupos de experimentos
Podemos comprovar esta diferença no tempo de resposta através da comparação dos
valores de tempo de resposta entre o grupo de experimentos Elastic-Clustered-Stateful e os
4.2. RESULTADOS
76
grupos Direct-Stateless e Direct-Stateful. Considerando o tempo de resposta como uma variável
aleatória T , que possui uma distribuição não normal. Podemos definir como hipótese nula que
T1 = T2 , ou como hipótese alternativa que o valor de T1 < T2 , onde T1 corresponde ao tempo de
resposta do grupo de experimentos Elastic-Clustered-Stateful e T2 aos tempos de resposta dos
experimentos Direct-Stateless e Direct-Stateful.
Tabela 4.5: Teste estatístico Mann-Whitney comparando os grupos de experimento
Elastic-Clustered-Stateful e Elastic-Clustered-Stateless
Número de
Clientes
50
50
50
50
100
100
100
100
150
150
150
150
200
200
200
200
Número de
Iterações
8000
16000
32000
64000
8000
16000
32000
64000
8000
16000
32000
64000
8000
16000
32000
64000
U
P-Value
91278977
24948474
6066395.5
1261866
91278977
24948474
6066395.5
1261866
91278977
24948474
6066395.5
1261866
91278977
24948474
6066395.5
1261866
1.00
1.00
0.26
1.00e-31
1.00
1.00
0.26
1.00e-31
1.00
1.00
0.26
1.00e-31
1.00
1.00
0.26
1.00e-31
4.2. RESULTADOS
77
Tabela 4.6: Teste estatístico Mann-Whitney comparando os grupos de experimento
Elastic-Clustered-Stateful e Elastic-Clustered-Stateful
Número de
Clientes
50
50
50
50
100
100
100
100
150
150
150
150
200
200
200
200
Número de
Iterações
8000
16000
32000
64000
8000
16000
32000
64000
8000
16000
32000
64000
8000
16000
32000
64000
U
P-Value
87649073.5
24387313.5
5805891.5
1223735
87649073.5
24387313.5
5805891.5
1223735
87649073.5
24387313.5
5805891.5
1223735
87649073.5
24387313.5
5805891.5
1223735
1.00
1.00
0.08
1.04e-31
1.00
1.00
0.08
1.04e-31
1.00
1.00
0.080
1.04e-31
1.00
1.00
0.08
1.04e-31
Como a variável aleatória T não possui uma distribuição normal, foi aplicado o teste
estatístico Mann-Whitney, com nível de significância 0.05. Os valores dos testes estatísticos,
que mostram uma comparação dos grupos de experimentos Elastic-Clustered-Stateful e DirectStateless, podem ser encontrados na Tabela 4.5 e a comparação entre os grupos Elastic-ClusteredStateful e Direct-Stateful na Tabela 4.6. O valor U representa o valor do teste estatístico
Mann-Whitney. Apenas nos experimentos onde o número de iterações é igual a 64000, pudemos
rejeitar a hipótese nula. Para este valor do número de iterações, o tempo de resposta do grupo de
experimentos Elastic-Clustered-Stateful é menor. Em todos os outros casos, pudemos observar
que a hipótese nula foi aceita.
Podemos observar os valores de vazão, de todos os grupos de experimentos, comparados
através da Figura 4.2. O grupo de experimentos Elastic-Clustered-Stateless apresentou um valor
bastante superior da métrica vazão, para qualquer valor de número de iterações e número de
clientes. Já os grupos Elastic-Clustered-Stateful, Direct-Stateless e Direct-Stateful apresentaram
valores de vazão bastante semelhantes.
4.2. RESULTADOS
78
(a) Vazão vs número de clientes com número de
iterações igual a 8000
(b) Vazão vs número de clientes com número de
iterações igual a 16000
(c) Vazão vs número de clientes com número de
iterações igual a 32000
(d) Vazão vs número de clientes com número de
iterações igual a 64000
Figura 4.2: Gráficos de barra para comparação de vazão entre todos os grupos de
experimentos
A Figura 4.3 mostra o comportamento do tempo de resposta ao longo do experimento.
Foram escolhidos os valores de 50 e 200 para o fator número de clientes e os valores 8000 e
64000 para o fator número de iterações, pois estes representam os maiores e menores níveis de
cada fator. Todos os grupos de experimento foram tratados em cada gráfico.
4.2. RESULTADOS
79
(a) Tempo de resposta vs tempo do experimento
para os valores de 50 clientes e 8000 iterações
(b) Tempo de resposta vs tempo do experimento
para os valores de 50 clientes e 64000 iterações
(c) Tempo de resposta vs tempo do experimento
para os valores de 200 clientes e 8000 iterações
(d) Tempo de resposta vs tempo do experimento
para os valores de 200 clientes e 64000 iterações
Figura 4.3: Tempo de resposta vs tempo do experimento para comparação entre os
grupos de experimentos
No início do experimento é comum, na fase de ramp-up, apresentar valores de tempo de
resposta que aumentam lentamente antes do primeiro minuto. Após a fase de ramp-up, o tempo
de resposta tende a aumentar um pouco mais até atingir um ponto de saturação, que ocasiona em
um valor estável para o tempo de resposta. Durante o início de alguns experimentos, foi possível
observar um pico repentino no tempo de resposta, mas que logo em seguida alcançou os valores
de ramp-up comuns.
Nos grupos de experimentos Elastic-Clustered-Stateless e Elastic-Clustered-Stateful
foram adicionados novos nós nos intervalos de 2, 4, 6 e 8 minutos do tempo do experimento.
4.3. DISCUSSÃO
80
Particularmente no experimento Elastic-Clustered-Stateless, podemos observar picos no tempo
de resposta quando são alcançados estes instantes, seguidos por quedas bruscas no tempo de
resposta, atingindo um ponto de saturação inferior ao anterior. Ao final de cada experimento do
grupo Elastic-Clustered-Stateless, o valor do tempo de resposta deste grupo de experimentos é
inferior ao dos demais grupos.
Os grupos Direct-Stateless e Direct-Stateful apresentaram um comportamento bastante
similar em todos os experimentos, visto que não há muita diferença entre eles. Já o grupo de
experimentos Elastic-Clustered-Stateful apresentou comportamento similar as Figuras 4.3a, 4.3b
e 4.3c, apresentando um ponto de saturação inferior apenas no gráfico mostrado na Figura 4.3d.
4.3
Discussão
Pudemos verificar que o grupo de experimentos Elastic-Clustered-Stateless apresentou
o melhor desempenho para todos os valores de número de clientes e número de iterações, no
cenário testado. Este comportamento era esperado, pois neste grupo a carga de trabalho do cliente
é distribuída entre vários servidores virtuais, utilizando mecanismos eficientes de balanceamento
de carga.
Foi possível observar também a redução no tempo de resposta proporcionado pela
adição de novos nós à infraestrutura durante os experimentos do grupo Elastic-Camid-Stateless,
mostrando que os mecanismos de coordenação e balanceamento de carga do eCaMid podem
responder rapidamente à adição de novos nós. Contudo, os picos no tempo de resposta que
ocorreram nos gráficos 4.3a, 4.3c e 4.3d, mostram o custo de coordenação relacionado à adição de
novos nós. No entanto, estes picos, em nenhum dos casos, ocasionaram uma perda significativa
do desempenho ao longo do experimento.
O grupo de experimentos Elastic-Clustered-Stateful, não apresentou uma melhora significativa nos tempos de resposta, a não ser quando foi utilizado um valor de 64000 para o parâmetro
número de iterações. Esta diferença tornou-se mais evidente conforme o número de clientes se
aproximava do maior valor, ou seja, 200 clientes. O ganho no tempo de resposta foi ocasionado
pelo uso dos mecanismos de balanceamento de carga, visto que o sistema como um todo possuía
um ponto de saturação menor para esta métrica. Já a vazão do sistema não foi afetada, mesmo
quando foram usados os maiores valores dos parâmetros de número de iterações e números
clientes.
Contudo, torna-se evidente que o mecanismo de compartilhamento de estado entre os
nós tem um grande impacto sobre o desempenho do middleware, especialmente se comparado ao
grupo de experimentos Elastic-Clustered-Stateless, uma vez que este grupo apresentou valores
menores de tempo de resposta e maiores de vazão em todos os experimentos realizados. Este
custo é compensado pela capacidade de manter o estado do sistema acessível a todos os nós
conforme estes são adicionados à infraestrutura e ao mesmo tempo evitar que este estado seja
perdido em caso de desligamento de um nó.
81
5
Trabalhos Relacionados
Neste capítulo, serão explicados os vários trabalhos que estão relacionados ao eCaMid.
Serão examinadas as tecnologias usadas pelo eCaMid para prover seus mecanismos de coordenação e compartilhamento de estado. Ao mesmo tempo, discutiremos os vários trabalhos de
middleware desenvolvidos nos últimos anos que tem como foco o desenvolvimento e integração
e gerenciamento de aplicações no ambiente de computação em nuvem.
5.1
Tecnologias fundamentais usadas pelo ElasticCamid
Na capítulo 3, nós citamos algumas tecnologias que são usadas como blocos básicos
para os mecanismos de coordenação e compartilhamento de estado do eCaMid: JGroups,
que fornece blocos básicos para implementação de comunicação em grupo (MONTRESOR;
DAVOLI; BABAOGLU, 2001); e Infinispan, um Datagrid que provê uma API chave-valor para
armazenamento de objetos, com suporte a transações, queries, transações, expiração e revogação
de dados (MARCHIONI, 2012).
5.1.1
JGroups
JGroups (MONTRESOR; DAVOLI; BABAOGLU, 2001) é um toolkit que permite a
utilização de comunicação em grupo em uma aplicação distribuída. JGroups implementa o
padrão Object Group (MAFFEIS et al., 1996), oferecendo para a aplicação um conjunto de
callbacks que são utilizados para implementar operações específicas de comunicação em grupo,
como criação de View, compartilhamento de estado, recepção de mensagens e detecção de falhas.
Um dos componentes principais fornecidos pelo JGroups, é chamado de JGroups (BAN;
BLAGOJEVIC, 2013). Através do JGroups é possível criar uma conexão a um grupo existente,
obter o endereço dos membros existentes, incluindo o próprio endereço e enviar mensagens
para os demais membros. As callbacks de comunicação de grupo são registradas pela aplicação
através do JGroups.
O JGroups depende de uma pilha de protocolos que, quando agrupados, oferecem
um conjunto de funcionalidades a aplicação. Os primeiros protocolos da pilha do JGroups
5.1. TECNOLOGIAS FUNDAMENTAIS USADAS PELO ELASTICCAMID
82
estão relacionados à camada de transporte da pilha de protocolos TCP/IP, e incluem suporte a
TCP e UDP. Logo acima dos protocolos de transporte, existem os protocolos de descoberta de
membros, responsáveis por realizar o bootstrapping da comunicação em grupo e detecção de
novos membros. Os próximos protocolos da pilha oferecem funcionalidades auxiliares como
descoberta de nós indisponíveis, fragmentação e ordenamento de mensagens, garbage collection
de mensagens recebidas e outros. Acima destes protocolos auxiliares, estão os serviços de
gerenciamento de grupo, que adicionam ou removem membros de um grupo e acionam os
callbacks de mudança na View.
Acima dos protocolos e JGroups, JGroups também oferecem um conjunto de blocos
básicos, que permitem a utilização das seguintes funcionalidades: comunicação request-reply
síncrona ou assíncrona com o uso de Futures, com suporte a unicast e multicast; serviços
de locking e contador distribuídos; execução de jobs em cluster; e finalmente, tabelas hash
distribuídas.
Apesar de prover inúmeras funcionalidades, vários recursos do JGroups são bastante
complexos, e por isso, de difícil utilização em uma aplicação de mais alto nível. O JGroups é
útil como parte da camada infraestrutura de um middleware mais complexo (MONTRESOR;
DAVOLI; BABAOGLU, 2001). O eCaMid utiliza o JGroups justamente neste tipo de situação,
onde provê abstrações de mais alto nível como objetos remotos, tarefas e subscribers, e criando a
"cola"necessária para utilizar o JGroups para seus mecanismos de comunicação e coordenação
de nós de forma transparente para a aplicação.
5.1.2
Infinispan
Mencionamos no capítulo 3, que o Storage Service do eCaMid utiliza o Infinispan
(MARCHIONI, 2012) para criar uma série de repositórios distribuídos que são utilizados pelos
componentes Naming Service, Management Services (Local Manager e Global Manager) e
Lifecycle Manager. O Infinispan é utilizado por servidores de aplicação como o JBoss Application
Server (CHAUDHARY et al., 2014) para prover mecanismos de cache e armazenamento de
dados (como sessões HTTP) em memória, em um ambiente distribuído (SURTANI et al., 2014).
O Infinispan utiliza o JGroups em sua camada de infraestrutura para prover mecanismos
de comunicação Peer-to-Peer (P2P) entre nós de um cluster. A partir desta camada de comunicação, o Infinispan oferece suporte a replicação de dados, transações distribuídas, queries e
mecanismos de expiração de dados. O infinispan pode ser executado como um banco de dados
distribuído, ou pode ser funcionar de forma embarcada em uma aplicação.
O infinispan possui três modos de funcionamento: replicação, invalidação e distribuição.
No modo de replicação, toda informação armazenada em um nó é replicada a todos os demais
nós de um cluster. Este modo de funcionamento depende da utilização de mecanismos de
multicast fornecidos pelo JGroups. A escalabilidade do modo replicação é comprometida à
medida que mais nós são adicionados ao cluster Infinispan, visto que o custo de sincronização
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
83
das informações torna-se mais alto.
No segundo modo de operação, invalidação, o Infinispan não compartilha o estado com
outros nós, mas opera como um cache para um banco de dados externo. Objetos extraídos do
banco de dados externo são armazenados localmente na memória de um nó. Caso o objeto
seja atualizado no banco de dados, uma mensagem de invalidação é enviada para os nós que
armazenam o objeto na memória, que removem o objeto do cache.
No modo de distribuição, o Infinispan utiliza uma função de hashing para determinar em
que nós uma determinada informação será armazenada. Quando a aplicação armazena um objeto
através da API chave-valor, a função de hashing é aplicada a chave. O hash gerado é utilizado
para determinar a que segmento o objeto será armazenado. A cada segmento é designado um
certo número de nós, chamados de donos. Um dos donos é chamado de dono primário, e os
demais são chamados de donos backup. Logo, caso um dono primário torne-se indisponível, um
dos donos backup assumirá o lugar de dono primário.
Um conjunto de segmentos constituem um espaço espaço de chave. O tamanho do
espaço de chave é configurável, mas adota um valor de 100 segmentos por padrão. À medida que
novos nós são adicionados ou removidos de um cluster, o Infinispan distribui os nós existentes
de forma homogênea entre os segmentos. A função de hashing utilizada para mapear chaves de
objetos tende a distribuir de forma igual os objetos entre os segmentos existentes. Isso é possível
porque o Infinispan utiliza uma função de hashing consistente, que é comum em implementações
de Distributed Hash Tables (DHTs) encontrados na literatura (SHEN; XU, 2008) (GUPTA et al.,
2003).
O modo distribuído do Infinispan permite que este possa manter a escalabilidade mesmo
que milhares de nós sejam adicionados à infraestrutura, visto que o estado de um objeto é
replicado apenas para uma fração dos nós do cluster. O eCaMid adota, por padrão, o Infinispan
em seu modo distribuído e embarcado, visando simplificar o processo de implantação do mesmo
e tornar possível que sejam adicionados milhares de nós à infraestrutura do middleware.
5.2
Trabalhos de Middleware Desenvolvido para Nuvem
É possível encontrar na literatura um grande número de trabalhos sobre middleware
para computação em nuvem. Estes trabalhos costumam abordar vários temas incluindo: uma
arquitetura geral para middleware no contexto de computação em nuvem (ABBADI, 2011a)
(ABBADI, 2011b); multi-tenacidade, ou a capacidade de compartilhar uma mesma infraestrutura
ou plataforma com múltiplas aplicações (AZEEZ et al., 2010) (KäCHELE; HAUCK, 2013);
interoperabilidade, seja por criar uma plataforma interoperável entre múltiplos provedores
(MAXIMILIEN et al., 2009) (MERLE; ROUVOY; SEINTURIER, 2011), ou criando meios
eficientes de comunicação entre nuvens (AMIN et al., 2012); elasticidade (RANJAN et al., 2010)
(JAYARAM, 2013), seja através de mecanismos que suportam a adição dinâmica de recursos
à infraestruta de nuvem ou o provisionamento automático de nós; requisitos não funcionais de
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
84
aplicações na nuvem, criando mecanismos de suporte à segurança e confiabilidade (CAMPBELL;
MONTANARI; FARIVAR, 2012), tolerância a falhas (BEHL et al., 2012).
Nas próximas subseções, serão explicados esses vários trabalhos e seu relacionamento
com o eCaMid, discutindo seus pontos em comum e suas diferenças. Será também explorado
como o eCaMid pode evoluir com base nos mecanismos apresentados nos mesmos trabalhos.
5.2.1
Arquitetura Geral de Middleware
ABBADI (2011b), em seu trabalho, cita que a nuvem pode ser dividida em três camadas:
a camada física representa os servidores físicos, sistemas de armazenamento e rede de computadores; a camada virtual consiste nos recursos virtuais que são operam sobre a camada física;
por fim, a camada de aplicação contém as aplicações que são hospedadas na nuvem através
da camada virtual. Além destas três camadas horizontais, temos verticalmente a camada de
armazenamento de dados, rede e servidores. Middleware serve como cola entre estas camadas,
provendo serviços de adaptabilidade, resiliência, escalabilidade, disponibilidade e segurança.
Quatro elementos definem os objetivos da camada virtual, propriedades do usuário incluem requisitos da camada virtual que devem ser definidos pelo usuário, como características
de máquinas virtuais e armazenamento, SLAs, segurança e privacidade. Propriedades da infraestrutura são capacidades definidas pelos arquitetos da solução de nuvem, que compreendem
distribuição, redundância, confiabilidade e conectividade. Políticas de infraestrutura definem
controles para os operadores da nuvem. Mudanças e Incidentes representam mudanças na
configuração da camada virtual.
Além desses elementos, ABBADI (2011b) definiu que serviços de middleware da camada
virtual devem possuir um conjunto de funções. A primeira, a adaptabilidade, consiste em definir
um conjunto de ações em resposta a mudanças de configuração, que podem ser resultados de
falhas de componente, realocação e aumento de demanda. Estas ações acionam as capacidades
de escalabilidade, que instrui um aumento vertical (mais capacidade para um componente) ou
horizontal (mais componentes) na infraestruturavirtual. Parte das ações da função de adaptabilidade ativam a função chamada de arquiteto do sistema, que por sua seleciona uma arquitetura
para a adaptação que deve ser realizada, com base na escalabilidade, gerenciamento de processos
e redundância. O arquiteto do sistema aciona a função de resiliência, que representa ações de
administradores do sistema, fazendo com que a comunicação entre servidores e dispositivos de
rede mantenham a comunicação e mesmo em caso de falha. A função de resiliência oferece
suporte às funções de confiabilidade, responsável por manter a integridade do sistema evitando
que dados ou informações sejam perdidos, e disponibilidade, que possui distribui requisições e
oferece caminhos redundantes de comunicação entre os componentes da infraestrutura virtual.
Os serviços de middleware na camada de aplicação devem implementar funções semelhantes – adaptabilidade, escalabilidade, resiliência, disponibilidade e confiabilidade –, mas
voltadas para o gerenciamento de recursos virtuais (ABBADI, 2011a). Três tipos de middleware
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
85
podem ser usados na camada de aplicação para suportar estas funções. O Server Backend
Middleware suporta sistemas de armazenamento em máquinas virtuais dedicadas. O Server
Middle-tier Middleware suporta servidores de aplicação e web, que podem ser combinados
de diferentes formas, e executados sobre uma mesma ou múltiplas máquinas virtuais. Já o
Client Frontend Middleware é responsável por tornar o acesso ao Server Middle-tier Middleware
transparente.
O eCaMid pode ser classificado como um middleware da camada de aplicação. Sua
arquitetura possui uma parte cliente e uma parte servidor, que podem representar, respectivamente,
Client Frontend Middleware e o Server Middle-tier Middleware. O eCaMid implementa as
funções de resiliência, através do protocolo do Naming Service, disponibilidade, através do Load
Balancing Service e Group Communication Framework e confiabilidade através do Storage
Service.
5.2.2
Multitenancy
Multitenancy é a capacidade de múltiplos tenants fazerem uso do mesmo recurso de
forma isolada e independente. No caso de middleware para nuvem, múltiplas aplicações ou
módulos podem compartilhar de um mesmo conjunto de máquinas virtuais, ou de um conjunto
de nós de um middleware. A implementação atual do eCaMid não possui suporte a multitenancy.
O uso de multitenancy, no entanto, beneficiaria este middleware, por oferecer mecanismos de
suporte mais granulares à elasticidade.
AZEEZ et al. (2010), em seu trabalho, propõe um middleware baseada em SOA para
desenvolvimento e execução de serviços e composições utilizando multitenancy. Aplicações em
SOA, neste contexto, podem ser divididos em execução, segurança e dados. A parte de execução
consiste de vários Web Services e composições dos mesmos em Workflows e Mashups. Dados
são armazenados através de bancos de dados e outros sistemas de armazenamento e usados
pelos elementos de execução. Segurança pode ser definida através de serviços de autenticação,
autorização, não-repudiação e confiabilidade que são ortogonais aos elementos de execução e
dados.
O middleware proposto por AZEEZ et al. (2010) chama-se WSO2 Carbon. No cerne
do middleware, há módulo central, chamado de Core, um motor que é responsável pelo carregamento, linking e execução de componentes de aplicação e gerenciamento do middleware,
baseados no padrão Open Service Gateway initiative (OSGi). Web Services das aplicações são
disponibilizados como bundles OSGi e gerenciados pelo Core. Um módulo Security disponibiliza para a aplicação serviços de gerenciamento de usuários, autenticação e autorização. O
isolamento entre diferentes aplicações é provido através do módulo de Service Execution, que
impede que as execuções e dados de cada tenant se mantenham isolados, protegendo-os por
exemplo, do uso de código malicioso para alterar o comportamento dos serviços. O módulo Data
Access provê uma abstração para acesso a registros e repositórios de dados do Core, incluindo
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
86
localização de serviços. Da mesma forma que o Service Execution o módulo de Data Access
provê isolamento de acesso entre diversos tenants. Todos estes módulos são executados sobre um
motor de execução chamado de Apache Axis2, que permite a implantação de vários componentes.
No trabalho desenvolvido por KäCHELE; HAUCK (2013), foi desenvolvido um middleware com suporte a multitenancy chamado COSCA que usa um modelo de programação
inspirado em OSGi. Este middleware introduz um conceito chamado de frameworks virtualizados, que tem a capacidade de mapear um conjunto de bundles em uma aplicação, onde cada
aplicação é mantida de forma isolada. Múltiplos frameworks são executados sobre uma mesma
Java Virtual Machine (JVM), de forma isolada, em múltiplos classloaders sob a gerência de um
security-manager. Cada JVM é executada sobre um servidor físico separado, sem a necessidade
de uma intermediação de uma camada de IaaS. O COSCA, desta forma, constitui um PaaS que
opera diretamente sobre uma plataforma de hardware.
Esta plataforma também mantém um componente chamado Distributed Service Registry,
que funciona como um componente central utilizado para registrar serviços de aplicações
cadastrados em cada nó, como um serviço de Lookup. Cada JVM mantém um serviço de
monitoramento que verifica a utilização decada componente de uma aplicação através da medição
do uso de CPU e chamada de serviços. Quando um componente está consumindo uma grande
quantidade de recursos, ele é implantado em outro nó, com replicação. Quando uma única JVM
está com todos os seus recuros exauridos, um dos componentes da aplicação é migrado para
outro nó. A implantação é possível graças a um serviço de provisionamento compatível com
OSGi (KäCHELE; HAUCK, 2013).
O COSCA, possui algumas limitações quanto acoplamento entre diferentes componentes
de uma mesma aplicação (KäCHELE; HAUCK, 2013). Há situações em que estes componentes
não podem ser migrados e replicados separadamente. Por isso a estrutura deles é investigada, e
caso seja detectado um forte acoplamento entre os mesmos, estes são tratados como um único
componente. O middleware também não oferece suporte a compartilhamento de estado, o que
limita o potencial de escalabilidade por dificultar a replicação e composição de componentes
da aplicação. A estratégia utilizada neste caso é implementar o compartilhamento de estado
através de uma base de dados externa, como um banco de dados relacional ou um serviço de
coordenação como o Zookeeper (APACHE ZOOKEEPER, 2014).
Em ambos os trabalhos foi constante a presença da tecnologia OSGi para implementar
mecanismos de modularização e multi-tenacidade. Um subsistema OSGi poderia ser adicionado
ao núcleo do eCaMid e definir serviços que garantam a segurança e isolamento de aplicações.
Este mecanismo poderia implementado no eCaMid para para oferecer um controle de elasticidade
mais granular, onde múltiplas aplicações compartilham do mesmo conjunto de máquinas virtuais.
Da mesma forma, o COSCA poderia se beneficiar dos mecanismos de balanceamento
de carga e compartilhamento de estado do eCaMid, que tornaria o serviço mais adequado à
implantação em máquinas virtuais e não dependeria de mecanismos armazenamento de estado e
coordenação externos.
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
5.2.3
87
Interoperabilidade
A interoperabilidade, no contexto de computação em nuvem, pode ter dois significados:
um mecanismo de comunicação destinado a integrar diferentes aplicações executadas em múltiplas nuvens; uma plataforma que possa ser executada por muitas linguagens de programação,
em diversos provedores diferentes de nuvem.
O trabalho desenvolvido por AMIN et al. (2012) constitui o primeiro tipo de interoperabilidade. O Intercloud Message Exchange Middleware (ICME) é um middleware que utiliza
um padrão de comunicação por troca de mensagens e presença, chamado de Data Distribution
Service (DDS), desenvolvido pelo Object Modeling Group (OMG). O serviço DDS depende de
um componente chamado de Global Data Space (GDS), que funciona como um ponto central
para o registro de tópicos, em um estilo de comunicação Publish/Subscribe, que desacopla os
participantes da comunicação.
O ICME extende as funcionalidades providas pelo DDS, através da definição de um
modelo de informação que reflete um cenário de computação em nuvem. Os participantes
do modelo de informação fornecido pelo ICME são chamados de entidade. Um dos tipos de
entidade é chamado de Message, que por sua vez pode ser de do tipo Request e Response. A
entidade define os tipos possíveis de mensagem é denominado MessageType, e consiste em
uma enumeração que possui uma entrada específica para cada mensagem. Cada mensagem se
relaciona com uma QoS Policy, que é definida através de um conjunto de QoS Parameters.
A entidade chamada Resource Description contém uma descrição de todos os recursos
da nuvem sob uma representação em forma de ontologia, descrito através do formato Web
Ontology Language (OWL) (AMIN et al., 2012). A ontologia armazenada por esta entidade
reflete a estrutura de implantação da nuvem, com cada nível hierarquia representando um objeto
diferente como fornecedor, middleware,aplicação, capacidade, sistema operacional e outros.
Esta ontologia é usada em conjunto com QoS Policies, que identificam o melhor caminho para a
entrega de um Message para um Subscriber específico.
O modelo de comunicação oferecido pelo ICME é próprio para interação entre aplicações
cujas partes são executada em domínios distintos. O eCaMid, em contrapartida foi pensado para
ser executado em uma única nuvem, como um cluster único. O ICME poderia ser utilizado
como intermediário de múltiplos clusters do eCaMid, cada um implantado em um conjunto de
recursos diferentes, como, por exemplo, diferentes provedores de nuvem presentes em uma única
federação.
O segundo tipo de interoperabilidade é implementado pelo middleware conhecido como
IBM Altocumulus (MAXIMILIEN et al., 2009). O IBM Altocumulus visa tornar possível
a implantação de uma aplicação sobre múltiplos provedores de IaaS públicos (i.e. AWS),
provedores de PaaS (i.e. GAE) e nuvens privadas (como Eucalyptus). Além dos provedores de
nuvem, o middleware também visa a implantação de aplicações em diferentes linguagens de
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
88
programação e frameworks, como Ruby on Rails 1 , Python/Django 2 , JavaEE3 e Hadoop 4 . Por
suportar esses diferentes frameworks, o Autocumulus visa execução de diferentes tarefas em
múltiplas nuvens, como é o caso de criar instâncias, executar imagens e configurar componentes.
Também é objetivo do middleware permitir a repetição da execução das mesmas tarefas, regras e
topologias em múltiplas nuvens, assim como a capacidade de monitorar métricas que medem o
desempenho das aplicações.
A arquitetura do Altocumulus é composto de um dashboard, que define uma interface
para usuários do middleware, destinadada a definir as melhores práticas de implantação de
aplicações e gerenciar as credenciais de acesso à diferentes provedores de nuvem. A API e
o API Tester são componentes que expõem a API Representational state transfer (REST) do
Altocumulus. O Core é um componente que implementa a API, que é usada pelo Dashboard
e as aplicações dos usuários. O Core contém um conjunto de scripts, regras e adaptadores de
nuvem que permitem a execução de ações em múltiplas nuvens para diferentes tipos de usuários
(MAXIMILIEN et al., 2009).
O eCaMid, assim como o Altocumulus, foi pensado como uma plataforma que pudesse
ser implantada em diversos provedores de nuvem. O eCaMid no entanto, tem um escopo mais
restrito, por ser pensado como um middleware que deve ser implantado em nuvens do tipo
IaaS para apoiar o desenvolvimento de aplicações orientadas a objeto que sejam compatíveis
com a tecnologia Java. No entanto, como o eCaMid é um middleware orientado a objetos, sua
principal função é fornecer um modelo de programação para aplicações de nuvem, enquanto o
Altocumulus provisiona e configura diferentes aplicações em diferentes tipos de nuvens diferentes.
O Altocumulus e o eCaMid poderiam funcionar de forma complementar, onde o primeiro seria
usado para provisionar e configurar o segundo em diferentes provedores e máquinas virtuais.
5.2.4
Elasticidade
A elasticidade é uma característica bastante peculiar ao modelo de computação em nuvem. A elasticidade é a capacidade de diminuir ou aumentar os recursos de nuvem de acordo com
a demanda da aplicação, evitando os riscos associados ao subdimensionamento e superdimensionamento da infraestrutura. Para que um middleware ofereça suporte a elasticidade, ele deve
apresentar meios para que a aplicação continue funcionando em decorrência da reconfiguração
dinâmica da infraestrutura ou que o middleware forneça serviços específicos que gerencie de
forma ativa a elasticidade, com a implantação e desligamento de outros nós. Os trabalhos que
serão mostrados a seguir procuram atender pelo menos uma dessas características.
RANJAN et al. (2010), em seu trabalho, desenvolveu um middleware baseado em uma
arquitetura P2P cuja finalidade é auxiliar na descoberta de serviços, provisionar aplicações em
1 http://rubyonrails.org/
2 https://www.djangoproject.com/
3 http://www.oracle.com/technetwork/java/javaee/overview/index.html
4 http://hadoop.apache.org/
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
89
nós específicos da infraestrutura de nuvem e proporcionar um mecanismo de balanceamento de
carga. A vantagem do uso de plataformas P2P no contexto de elasticidade é a sua capacidade
de se manter funcional mesmo em decorrência de desligamento e ativação de novas máquinas
virtuais, e de conter mecanismos de comunicação de alta escalabilidade.
O middleware conhecido como Cloud Peers é parte de uma oferta de PaaS e é composto
de três camadas. A primeira camdada consiste em uma infraestrutura de roteamento autoorganizável baseada em DHT, fornecendo um overlay para diversas máquinas virtuais, mantendo
uma tabela de roteamento para cada endereço IP de um peer. A segunda camada oferece
mecanismos de organização de dados, índices distribuído e replicação. Estes índices suportam o
armazenamendo de chaves e queries multidimensionais, onde cada registro é armazenado em
múltiplos nós, evitando a perda de informação em caso de falha de um peer. A terceira consiste
em serviços de descoberta de nós, coordenação e troca de mensagens. Através dos serviços da
terceira camada, são registrados as máquinas virtuais existentes, os serviços publicados em cada
um e mecanismos de troca de mensagens baseado no padrão Publish/Subscribe (RANJAN et al.,
2010).
O eCaMid também utiliza um mecanismo de comunicação P2P para localizar e coordenar
diversos nós baseada em JGroups, mas que funciona de forma diferente de uma DHT. eCaMid e
o Cloud Peers também diferem por suas finalidades. O principal foco do eCaMid é proporcionar
um modelo de programação baseado em objetos distribuídos. Já a finalidade do Cloud Peers é
prover mecanismos eficiente de provisionamento de aplicações em máquinas virtuais e oferecer
serviços de localização e coordenação.
Um outro trabalho tem a finalidade de prover serviços de elasticidade (JAYARAM, 2013).
O middleware chamado de ElasticRMI fornece uma extensão ao middleware Remote Method
Invocation (RMI), um middleware orientado a objetos que é parte do núcleo da linguagem java.
O ElasticRMI define um conceito de um Elastic Object Pool, um conjunto de objetos
(baseados no padrão Object Group), que está distribuído em diferentes nós de uma infraestrutura.
Invocações direcionadas a um dos objetos presentes no Elastic Object Pool são direcionadas aos
demais membros, como um mecanismo de balanceamento de carga. Um sistema de armazenamento chamado Hyperdex (HYPERDEX, 2014) é usado para armazenar o estado dos objetos
distribuídos. Um framework de gerenciamento de cluster, chamado Apache Mesos (APACHE
MESOS, 2014), é responsável por distribuir processos de um Elastic Object Pool entre várias
máquinas físicas ou virtuais (JAYARAM, 2013).
O eCaMid e o ElasticRMI são bastante semelhantes, pois ambos são middlewares
orientados a objetos que visam manter serviços de suporte à elasticidade. Ambos utilizam o
padrão de projeto Object Group para distribuir requisições remotas entre diversos nós.
Algumas características, no entanto, diferenciam o eCaMid e o ElasticRMI. Enquanto
o balanceamento de carga realizado pelo ElasticRMI é realizado para um grupo formado por
um conjunto de objetos semelhantes, o mesmo mecanismo, no eCaMid, é realizado para um
grupo de nós semelhantes de uma mesma infraestrutura. Um nó do eCaMid pode conter vários
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
90
objetos distribuídos, que possuem alguma dependência entre si. O eCaMid também suporta
estilos de comunicação Publish/Subscribe e a coordenação de tarefas periódicas em um cluster.
O sistema de armazenamento e coordenação utilizado pelo eCaMid utiliza um modelo P2P que
é embarcado no próprio middleware visando facilitar o deployment e configuração, enquanto
o ElasticRMI depende de serviços instalados externamente como o Hyperdex e Apache Mesos.
Estes serviços também precisam ser provisionados e dimensionados visando os requisitos não
funcionais de escalabilidade, desempenho e disponibilidade para que o ElasticRMI possa adquirir
estas mesmas características.
O ElasticRMI, no entanto, é capaz de realizar o redimensionamento do tamanho de um
Elastic Object Pool dinamicamente, baseado em métricas de desempenho. Embora provedores
de nuvem, tipicamente, não possuam instalações nativas de um framework como Apache Mesos,
este poderia ser útil como parte de uma oferta de PaaS. O eCaMid ainda carece de um mecanismo
semelhante, e poderia se beneficiar de ferramentas de provisionamento e implantação.
5.2.5
Outros requisitos não funcionais de nuvem
Diferentes requisitos não funcionais de computação em nuvem podem motivar o desenvolvimento de arquiteturas e a criação de serviços de middleware. Entre os requisitos mencionados
nesta seção, temos segurança, confiabilidade e tolerância à falhas.
O trabalho desenvolvido por CAMPBELL; MONTANARI; FARIVAR (2012) define
uma arquitetura de middleware para aplicações de missão crítica executadas em um ambiente
de computação em nuvem. Estes ambientes precisam suportar requisitos restritos de segurança,
disponibilidade e desempenho em tempo real. Aplicações de missão crítica precisam ser sobretudo confiáveis, com a garantia que determinada operação foi realmente concluída em um
intervalo predeterminado. Para que seja possível garantir estes requisitos, deve ser possível
utilizar mecanismos de monitoramento robustos, que possam identificar de forma imediata e
confiável problemas de segurança e disponibilidade. Ao mesmo tempo este middleware de
missão crítica precisa de agentes que respondam de imediato à violações detectadas.
O middleware for assured clouds contém um subsistema composto por agentes que
recebem eventos de diversas fontes, sejam estas externas como é o caso de switches openflow,
dispositivos que utilizam o protocolo Simple Network Management Protocol (SNMP) (roteadores
e switches) e Intrusion Detection Systems (IDSs), ou de fontes internas, que utilizam agregadores
de evento que fazem parte da infraestrutura do middleware. Estes eventos coletados por um agente
são encaminhados a um motor de inferência de regras interno ao próprio agente, que verificam
problemas de conformidade. Caso seja detectado uma violação de conformidade, estes devem
notificar os componentes que administram os sistemas de comunicação, gerando mudanças
na configuração e comportamento, impedindo que novos erros sejam repetidos (CAMPBELL;
MONTANARI; FARIVAR, 2012).
O eCaMid não foi pensado no contexto de aplicações de missão críticas, e não é meta
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
91
de seu desenvolvimento e evolução garantir estes requisitos. No entanto, os agentes de monitoramento descritos por CAMPBELL; MONTANARI; FARIVAR (2012) poderiam ser providos
como módulos externos ao eCaMid, para satisfazer os requisitos não funcionais de aplicações
específicas.
BEHL et al. (2012), em seu trabalho, definiu uma solução para execução de diferentes
workflows baseados em web services, com suporte a tolerância a falhas. No núcleo da solução
desenvolvida, há um motor de processos de negócio compatível com a linguagem Business
Process Execution Language (WS-BPEL). Um processo de negócio é um fluxo de ações de
negócio complexas que invocam capacidades específicas de diversos web services, estes que
realizam operações de negócio de maior granularidade.
Motores WS-BPEL precisam guardar dados intermediários, tratar exceções e expressar
fluxos de execução. No entanto, infrastruturas tradicionais que utilizam esta tecnologia são
deficientes em mecanismos de tolerância a falhas. Para solucionar o problema, os motores
WS-BPEL e web services precisam ser replicados. Os web services, em particular, devem
ser acessados através de proxies, que usam um serviço de coordenação externo, o Zookeeper
(APACHE ZOOKEEPER, 2014). Este serviço de coordenação serve para armazenar configuração
e informação relevante para o sistema, detectar quando algum dos nós falha e realizar a ordenação
das requisições (BEHL et al., 2012). Uma definição de processo de negócio, ao ser carregada
pelo motor WS-BPEL, deve ser transformada para incluir estes proxies no lugar de chamadas
diretas aos webservices. As requisições entregues pelos motores de regra de negócio aos web
services devem conter uma semântica de At Most Once, para assegurar que uma operação de
negócio tenha sido realizada múltiplas vezes em um fluxo BEHL et al. (2012).
Assim como o eCaMid, o trabalho desenvolvido por BEHL et al. (2012) faz uso de um
mecanismos de coordenação de processos, neste caso o Zookeeper. O Zookeeper, no entanto,
atua de forma externa à aplicação, implantado como um conjunto de processos independentes.
5.2.6
Discussão
Foi possível observar nas subseções anteriores vários trabalhos que utilizam middleware
para implementar várias funcionalidades como multitenancy, interoperabilidade, elasticidade e
dar apoio a outros requisitos não funcionais de aplicações distribuídas. Muitos dos middlewares
desenvolvidos por estes trabalhos, no entanto, nem são middlewares orientados a objeto, nem
possuem foco em modelos de programação distribuídos.
Apenas parte desses trabalhos possuem implementação e foram testados em uma nuvem
real, como o eCaMid. Alguns dos trabalhos de middleware desenvolvidos nestas pesquisas
possuem mecanismos bastante similares aos implementados no eCaMid, mas que se diferenciam
por abordar estratégias diferentes ou modelos de programação distintos. Através deste estudo,
também foi possível verificar vários pontos de melhoria e avanços a serem implmentados em
trabalhos futuros.
5.2. TRABALHOS DE MIDDLEWARE DESENVOLVIDO PARA NUVEM
5.2.7
92
Considerações finais
Neste capítulo, foram listadas as tecnologias usadas pelo eCaMid para implementar seus
mecanismos de coordenação e compartilhamento de estado. Em seguida, foram mencionados
vários trabalhos que visam a utilização de middleware para implementar várias funcionalidades
como multitenacidade, interoperabilidade, elasticidade e dar apoio a outros requisitos não
funcionais. Uma breve discussão foi iniciada para elicitar a motivação do desenvolvimento do
eCaMid.
93
6
Considerações Finais
Os primeiros capítulos explicaram as principais motivações para o desenvolvimento
do eCaMid e as ideias básicas que fundamentam os conceitos utilizados na concepção da sua
arquitetura. Foram explicados os principais conceitos de computação em nuvem e elasticidade.
Também foi realizado um estudo sobre os padrões arquiteturais e de projeto, e seus relacionamentos, para definir os blocos básicos e uma linguagem padrão para os componentes do projeto
do eCaMid.
O terceiro capítulo introduziu os aperfeiçoamentos realizados à arquitetura original,
para aprimorar o suporte à elasticidade. Como contribuições principais do eCaMid, podemos
mencionar o uso de mecanismos de coordenação, replicação e balanceamento de carga, que
visam aumentar a escalabilidade do middleware quando novos nós são adicionados, e continuar
funcionando quando esses nós são desligados. Adicionalmente, o eCaMid introduziu novas
funcionalidades (tarefas periódicas, e comunicação Publish/Subscribe) que aumentam o escopo
do eCaMid para tipos de carga de trabalho que são complementares ao estilo de comunicação de
middlewares orientados a objetos e são relevantes para o paradigma de computação em nuvem.
Uma avaliação experimental foi usada, no quarto capítulo, para avaliar o comportamento
do eCaMid em diferentes cenários. Dada as condições do experimento, os mecanismos de
balanceamento de carga do eCaMid mostraram um melhor resultado quando foram utilizados
objetos remotos que não possuem estado. Quando esses objetos remoto possuem estado, a
sincronização deste entre vários nós apresentou uma perda considerável de desempenho, mas em
contrapartida, tornou possível que o mesmo objeto fosse acessado consistentemente entre vários
nós.
No quinto capítulo, foi realizado um breve estudo sobre os trabalhos de middleware que
foram desenvolvidos para a nuvem. Foram identificados diversos pontos comuns e divergentes
entre o eCaMid e esses trabalhos, assim como estratégias usadas nestes que podem servir como
melhorias para o eCaMid em trabalhos futuros.
Através deste trabalho foi possível criar um middleware orientado a objetos que é capaz de
utilizar a elasticidade de um ambiente de nuvem para aprimorar seus mecanismos de distribuição.
Este middleware se baseou mas melhores práticas para o desenvolvimento de aplicações na
6.1. TRABALHOS FUTUROS
94
nuvem, levando em conta as peculiaridades deste ambiente e desenvolveu mecanismos de suporte
à elasticidade dentro do próprio middleware.
Ainda que o eCaMid careça da mesma maturidade de outras soluções de middleware
do mercado e da academia, este pode servir como prova de conceito para implementação de
mecanismos de suporte à elasticidade em outras plataformas mais maduras. Os mecanismos
usados neste trabalho podem também ser adaptados para outros tipos de modelo de comunicação,
como é o caso de servidores web, balanceadores de carga inteligentes e servidores de aplicação.
6.1
Trabalhos Futuros
A evolução do eCaMid pode ser realizada em diversas direções. O sistema atual de
sincronização de estado do eCaMid é limitado pelas capacidades do Infinispan, que provê as
abstrações necessárias para a implementação de um serviço de armazenamento em memória
distribuído. O eCaMid pode ser expandido para utilizar outros key-value stores distribuídos,
como é o caso do Redis1 e Memcached2 . O desempenho destas soluções de armazenamento
pode ser comparado e avaliado em que cenários cada uma dessas tecnologias apresenta o melhor
resultado.
O suporte à elasticidade pode ser aprimorado através da implementação de um serviço
que realize a implantação e provisionamento de máquinas virtuais de forma automática, com base
em parâmetros de qualidade coletados a partir dos componentes de gerenciamento do eCaMid.
O uso de multitenancy possibilitará um controle mais granular sobre a elasticidade, provendo
isolamento a múltiplas aplicações em um mesmo cluster do eCaMid.
O uso de interoperabilidade entre múltiplas nuvens pode favorecer à implantação do
eCaMid em um cenário multi-cluster. Este cenário consiste em um conjunto de clusters que
utilizam algum mecanismo de integração (como mensagens assíncronas) e balancemento de
carga de acordo garantias de nível de serviço de múltiplos provedores ou distribuição geográfica.
A implementação atual do eCaMid não oferece suporte a mecanismos de segurança. Esta
implementação poderia ser estendida para incluir serviços de autenticação e controle de acesso
baseado em políticas e papéis.
1 http://redis.io/
2 http://memcached.org/
95
Referências
ABBADI, I. Middleware Services at Cloud Virtual Layer. In: COMPUTER AND
INFORMATION TECHNOLOGY (CIT), 2011 IEEE 11TH INTERNATIONAL
CONFERENCE ON. Anais. . . [S.l.: s.n.], 2011. p.115–120.
ABBADI, I. M. Middleware Services at Cloud Application Layer. In: ABRAHAM, A.
et al. (Ed.). Advances in Computing and Communications. [S.l.]: Springer Berlin
Heidelberg, 2011. p.557–571. (Communications in Computer and Information Science, v.193).
10.1007/978-3-642-22726-4_58.
AMIN, M. B. et al. Intercloud Message Exchange Middleware. In: INTERNATIONAL
CONFERENCE ON UBIQUITOUS INFORMATION MANAGEMENT AND
COMMUNICATION, 6., New York, NY, USA. Proceedings. . . ACM, 2012. p.79:1–79:7.
(ICUIMC ’12).
APACHE JMeter. Accessed: 2014-04-30, http://jmeter.apache.org/.
APACHE Mesos. Accessed: 2014-07-20, http://mesos.apache.org/.
APACHE Zookeeper. Accessed: 2014-07-15, http://zookeeper.apache.org/.
AZEEZ, A. et al. Multi-tenant SOA middleware for cloud computing. In: CLOUD
COMPUTING (CLOUD), 2010 IEEE 3RD INTERNATIONAL CONFERENCE ON. Anais. . .
[S.l.: s.n.], 2010. p.458–465.
BABAR, M. A.; CHAUHAN, M. A. A Tale of Migration to Cloud Computing for Sharing
Experiences and Observations. In: ND INTERNATIONAL WORKSHOP ON SOFTWARE
ENGINEERING FOR CLOUD COMPUTING, 2., New York, NY, USA. Proceedings. . . ACM,
2011. p.50–56. (SECLOUD ’11).
BAKOUCH, H. S. Probability, Markov chains, queues, and simulation. Journal of Applied
Statistics, [S.l.], v.38, n.8, p.1746–1746, 2011.
BALIGA, J. et al. Green Cloud Computing: balancing energy in processing, storage, and
transport. Proceedings of the IEEE, [S.l.], v.99, n.1, p.149–167, Jan 2011.
BAN, B.; BLAGOJEVIC, V. Reliable group communication with JGroups 3.x. Accessed:
2014-06-30, http://www.jgroups.org/manual/html/index.html.
BEHL, J. et al. Providing Fault-tolerant Execution of Web-service-based Workflows Within
Clouds. In: ND INTERNATIONAL WORKSHOP ON CLOUD COMPUTING PLATFORMS,
2., New York, NY, USA. Proceedings. . . ACM, 2012. p.7:1–7:6. (CloudCP ’12).
BUSCHMANN, F.; HENNEY, K.; SCHMIDT, D. C. Pattern-Oriented Software
Architecture Volume 4: a pattern language for distributed computing (v. 4). [S.l.]: Wiley, 2007.
CALHEIROS, R. N. et al. The Aneka platform and QoS-driven resource provisioning for elastic
applications on hybrid Clouds. Future Generation Computer Systems, [S.l.], v.28, n.6, p.861
– 870, 2012. Including Special sections SS: Volunteer Computing and Desktop Grids and SS:
Mobile Ubiquitous Computing.
REFERÊNCIAS
96
CAMPBELL, R.; MONTANARI, M.; FARIVAR, R. A middleware for assured clouds. Journal
of Internet Services and Applications, [S.l.], v.3, n.1, p.87–94, 2012.
CHAUDHARY, N. et al. JBoss Enterprise Application Platform 6.2 Administration and
Configuration Guide. Accessed: 2014-06-30, https://access.redhat.com/
documentation/en-US/JBoss_Enterprise_Application_Platform/6.2/
html/Administration_and_Configuration_Guide/index.html.
DRAGO, I. et al. Inside Dropbox: understanding personal cloud storage services. In: ACM
CONFERENCE ON INTERNET MEASUREMENT CONFERENCE, 2012., New York, NY,
USA. Proceedings. . . ACM, 2012. p.481–494. (IMC ’12).
EMMERICH, W.; KAVEH, N. Component technologies: java beans, com, corba, rmi, ejb and
the corba component model. In: SOFTWARE ENGINEERING, 2002. ICSE 2002.
PROCEEDINGS OF THE 24RD INTERNATIONAL CONFERENCE ON. Anais. . . [S.l.: s.n.],
2002. p.691–692.
FOX, A. et al. Above the clouds: a berkeley view of cloud computing. Dept. Electrical Eng.
and Comput. Sciences, University of California, Berkeley, Rep. UCB/EECS, [S.l.], v.28,
p.13, 2009.
FURHT, B. Cloud Computing Fundamentals. In: FURHT, B.; ESCALANTE, A. (Ed.).
Handbook of Cloud Computing. [S.l.]: Springer US, 2010. p.3–19.
GAMMA, E. et al. Design Patterns: abstraction and reuse of object-oriented design. In:
NIERSTRASZ, O. (Ed.). ECOOP’ 93 — Object-Oriented Programming. [S.l.]: Springer
Berlin Heidelberg, 1993. p.406–431. (Lecture Notes in Computer Science, v.707).
GHOSH, S. Distributed systems: an algorithmic approach. [S.l.]: CRC press, 2010.
GORTON, I. Essential software architecture. [S.l.]: Springer, 2011.
GUPTA, I. et al. Kelips: building an efficient and stable p2p dht through increased memory and
background overhead. In: KAASHOEK, M.; STOICA, I. (Ed.). Peer-to-Peer Systems II. [S.l.]:
Springer Berlin Heidelberg, 2003. p.160–169. (Lecture Notes in Computer Science, v.2735).
HERRICK, D. R. Google This!: using google apps for collaboration and productivity. In:
ANNUAL ACM SIGUCCS FALL CONFERENCE: COMMUNICATION AND
COLLABORATION, 37., New York, NY, USA. Proceedings. . . ACM, 2009. p.55–64.
(SIGUCCS ’09).
HOHPE, G.; WOOLF, B. Enterprise integration patterns: designing, building, and deploying
messaging solutions. [S.l.]: Addison-Wesley Professional, 2004.
HOMER, A. et al. Cloud Design Patterns: prescriptive architecture guidance for cloud
applications. [S.l.]: Microsoft patterns &#38; practices, 2014.
HYPERDEX. Accessed: 2014-07-20, http://hyperdex.org/.
JAIN, R. The art of computer system performance analysis: techniques for experimental design,
measurement, simulation and modeling. New York: John Willey, [S.l.], 1991.
REFERÊNCIAS
97
JAYARAM, K. Elastic Remote Methods. In: EYERS, D.; SCHWAN, K. (Ed.). Middleware
2013. [S.l.]: Springer Berlin Heidelberg, 2013. p.143–162. (Lecture Notes in Computer Science,
v.8275).
JIN, H. et al. Tools and Technologies for Building Clouds. In: ANTONOPOULOS, N.;
GILLAM, L. (Ed.). Cloud Computing. [S.l.]: Springer London, 2010. p.3–20. (Computer
Communications and Networks).
KäCHELE, S.; HAUCK, F. J. Component-based Scalability for Cloud Applications. In:
INTERNATIONAL WORKSHOP ON CLOUD DATA AND PLATFORMS, 3., New York, NY,
USA. Proceedings. . . ACM, 2013. p.19–24. (CloudDP ’13).
KEMP, C.; GYGER, B. Professional Heroku Programming. [S.l.]: John Wiley & Sons, 2013.
KIRCHER, M.; JAIN, P. Pattern-oriented software architecture vol 3: patterns for resource
management. [S.l.]: Wiley, 2004.
LEWIS, G. Role of Standards in Cloud-Computing Interoperability. In: SYSTEM SCIENCES
(HICSS), 2013 46TH HAWAII INTERNATIONAL CONFERENCE ON. Anais. . . [S.l.: s.n.],
2013. p.1652–1661.
MAFFEIS, S. et al. The Object Group Design Pattern. In: COOTS. Anais. . . [S.l.: s.n.], 1996.
v.96, p.12–12.
MARCHIONI, F. Infinispan Data Grid Platform. [S.l.]: Packt Publishing Ltd, 2012.
MARSTON, S. et al. Cloud computing — The business perspective. Decision Support
Systems, [S.l.], v.51, n.1, p.176 – 189, 2011.
MAXIMILIEN, E. M. et al. IBM Altocumulus: a cross-cloud middleware and platform. In:
ACM SIGPLAN CONFERENCE COMPANION ON OBJECT ORIENTED PROGRAMMING
SYSTEMS LANGUAGES AND APPLICATIONS, 24., New York, NY, USA. Proceedings. . .
ACM, 2009. p.805–806. (OOPSLA ’09).
MERLE, P.; ROUVOY, R.; SEINTURIER, L. A reflective platform for highly adaptive
multi-cloud systems. In: ADAPTIVE AND REFLECTIVE MIDDLEWARE ON
PROCEEDINGS OF THE INTERNATIONAL WORKSHOP, New York, NY, USA. Anais. . .
ACM, 2011. p.14–21. (ARM ’11).
MONTRESOR, A.; DAVOLI, R.; BABAOGLU, O. Middleware for Dependable Network
Services in Partitionable Distributed Systems. SIGOPS Oper. Syst. Rev., New York, NY, USA,
v.35, n.1, p.73–96, Jan. 2001.
MORAIS, T. de; LIBERALQUINO, D.; ROSA, N. Cloud-Aware Middleware. In: ADVANCED
INFORMATION NETWORKING AND APPLICATIONS (AINA), 2013 IEEE 27TH
INTERNATIONAL CONFERENCE ON. Anais. . . [S.l.: s.n.], 2013. p.780–787.
OPENSTACK Cloud Administrator Guide. Accessed: 2014-06-20,
http://docs.openstack.org/admin-guide-cloud/content/.
RANJAN, R. et al. Peer-to-Peer Cloud Provisioning: service discovery and load-balancing. In:
ANTONOPOULOS, N.; GILLAM, L. (Ed.). Cloud Computing. [S.l.]: Springer London, 2010.
p.195–217. (Computer Communications and Networks).
REFERÊNCIAS
98
REESE, G. Cloud application architectures: building applications and infrastructure in the
cloud. [S.l.]: "O’Reilly Media, Inc.", 2009.
RIMAL, B.; CHOI, E.; LUMB, I. A Taxonomy, Survey, and Issues of Cloud Computing
Ecosystems. In: ANTONOPOULOS, N.; GILLAM, L. (Ed.). Cloud Computing. [S.l.]:
Springer London, 2010. p.21–46. (Computer Communications and Networks).
SADJADI, S. M.; MCKINLEY, P. K. A survey of adaptive middleware. Michigan State
University Report MSU-CSE-03-35, [S.l.], 2003.
SANDERSON, D. Programming Google App Engine: build and run scalable web apps on
google’s infrastructure. [S.l.]: "O’Reilly Media, Inc.", 2009.
SCHMIDT, D. C. Middleware for Real-time and Embedded Systems. Commun. ACM, New
York, NY, USA, v.45, n.6, p.43–48, June 2002.
SCHMIDT, D. C. et al. Pattern-Oriented Software Architecture, Patterns for Concurrent
and Networked Objects. [S.l.]: John Wiley & Sons, 2013. v.2.
SHEN, H.; XU, C.-Z. Hash-based proximity clustering for efficient load balancing in
heterogeneous {DHT} networks. Journal of Parallel and Distributed Computing, [S.l.], v.68,
n.5, p.686 – 702, 2008.
SIEGELE, L. Let it rise: a special report on corporate it. [S.l.]: Economist Newspaper, 2008.
SURTANI, M. et al. Infinispan User Guide. Accessed: 2014-06-30,
http://infinispan.org/docs/6.0.x/user_guide/user_guide.html.
TALUKDER, A.; ZIMMERMAN, L.; A, P. Cloud Economics: principles, costs, and benefits. In:
ANTONOPOULOS, N.; GILLAM, L. (Ed.). Cloud Computing. [S.l.]: Springer London, 2010.
p.343–360. (Computer Communications and Networks).
TURAN, M. S. et al. Recommendation for password-based key derivation. NIST special
publication, [S.l.], v.800, p.132, 2010.
VANBRABANT, R. Google Guice: agile lightweight dependency injection framework. [S.l.]:
Apress, 2008.
VARIA, J. Architecting for the cloud: best practices. Amazon Web Services, [S.l.], 2010.
VARIA, J.; MATHEW, S. Overview of amazon web services. Amazon Web Services, [S.l.],
2012.
VÖLTER, M.; KIRCHER, M.; ZDUN, U. Remoting Patterns: foundations of enterprise,
internet and realtime distributed object middleware. [S.l.]: Wiley. com, 2005.
WILDER, B. Cloud Architecture Patterns. [S.l.]: "O’Reilly Media, Inc.", 2012.
Download

DISSERTAÇÃO Diego Liberalquino Soares Lima