% \documentclass[a4paper,12pt,numbered]{book}
% 
% \usepackage{sbc2003}
% 
% \usepackage[pdftex]{graphicx}
% 
% \usepackage{url}
% \usepackage[portuges]{babel}
% \usepackage[latin1]{inputenc}
% \usepackage{epsfig}
%\usepackage{fullpage} 

%\sloppy

%\title{Grids Computacionais: De Computação de Alto Desempenho a Serviços sob %Demanda\thanks{Financiado por: HP Brasil e CNPq}}

%\author{Walfredo Cirne \and Elizeu Santos-Neto}

%\address{Laboratório de Sistemas Distribuídos\\
%Universidade Federal de Campina Grande\\
%Av. Aprígio Veloso, 882, Bloco CO -- 58109-970\\ 
%Campina Grande, PB\\
%\email{\{walfredo,elizeu\}@dsc.ufcg.edu.br}}

% \begin{document}
% 
% \setcounter{chapter}{1}
% 
% %\tableofcontents
% 
% \setcounter{page}{15}
% 
% %\pagestyle{plain}
% 
% %\maketitle
% \fontsize{18}{21.6} {\bf Capítulo}
% 
% \fontsize{36}{21.6} {\bf 1}
% 
% \fontsize{18}{24} {\bf Grids Computacionais: da Computação de Alto}
% 
% \fontsize{18}{24} {\bf Desempenho a Serviços sob Demanda}
% 
% \begin{center} \begin{large} Walfredo Cirne, Elizeu Santos-Neto~\footnote{Este trabalho foi
%     parcialmente desenvolvido em colaboração com a HP Brasil P\&D e conta com
%     suporte do CNPq.} \end{large} \end{center}
% 
% \normalsize

% \begin{center}
% Lab. de Sistemas Distribuídos - Univ. Federal de Campina Grande
% 
% Av. Aprígio Veloso, 882, Bloco CO -- 58109-970, Campina Grande, PB
% 
% \{walfredo,elizeu\}@dsc.ufcg.edu.br
% \end{center}

% \begin{center} {\bf Abstract} \end{center}
% 
% {\em Computational Grids has emerged in the 1990's as a promise to run
% parallel applications on widely dispersed computational resources,
% located at different institutions. The retionale was twofold. The first one
% was to provide a cheapear execution platform for parallel applications than
% supercomputers. The second was to allow the distributed applications execution
% using a number of resources that is impossible to achieve using only one
% supercomputer. The evolution of Grid technology shows that the automatic composition of a set
% of resources to respond to an application demand creates the opportunity to
% provide {\em services on demand}. Therefore, it has been conceived the idea of
% evolving the Grid to become possible infrastructures based on {\em any kind} of
% computational service on demand (not only high performance
% services). Consequently, the Grid has been merged with Web Services and these
% two technologies currently appears as a fundamental build block for computing in
% the {\sc xxi} century. This work describes the evolution of Computational Grids. It covers the main
% existent technologies. It also presents important aspects of creating Grids
% based on generic Services, as well as the specific characteristics of high
% performance Grids.}
\chapter{Grids Computacionais}
\label{grids}
\cutname{gridscomputacionais.html}

% \begin{center} {\bf Resumo} \end{center}

{\em Grids Computacionais surgiram em meados da década de 90 com a promessa de
viabilizar a execução de aplicações paralelas em recursos geograficamente
dispersos e pertencentes a múltiplas organizações. Tal proposta tinha dois
grandes apelos. O primeiro era o de fornecer uma plataforma muito mais barata
para execução de aplicações distribuídas (que os supercomputadores paralelos). O
segundo era possibilitar (através da aglomeração de recursos dispersos) a
execução de aplicações paralelas em uma escala simplesmente impossível em um
único supercomputador. Com a evolução da tecnologia de grids percebeu-se que
a composição automática de um conjunto de recursos para servir uma aplicação
criava a oportunidade de oferecer {\em serviços sob demanda}. Assim, surgiu a
idéia de um Grid onde seja possível prover sob demanda {\em qualquer} serviço
computacional (não somente serviços para com\-pu\-ta\-ção de alto desempenho). Como
conseqüência, as tecnologias de Grids Computacionais se fundiram com Web
Services e se posicionaram como uma tecnologia fundamental para computação no
século {\sc xxi}. O texto a seguir descreve a evolução dos Grids Computacionais, cobrindo as
principais tecnologias existentes, e apresentando os aspectos importantes para
criação de Grids de Serviços genéricos, bem como características específicas de
Grids para alto desempenho.}

\section{Introdução}
\label{sec:intro}

Grids Computacionais são atualmente uma das áreas mais ``quentes'' da
Computação. O que começou em universidades e institutos de pesquisa ganhou o
mundo empresarial e hoje faz parte da estratégia de corporações como IBM, HP,
Sun, NEC, Microsoft e Oracle. Em suma, temas relacionados a Grids Computacionais
figuram hoje como um assunto em moda.

Porém, o que afinal vem a ser um Grid Computacional? A visão original estabelece
  uma metáfora com A Rede Elétrica ({\em The Electric
  Grid})~\cite{foster-gridbook}. A Rede Elétrica disponibiliza energia elétrica
  sob demanda e esconde do usuário detalhes como a origem da energia e a
  complexidade da malha de transmissão e distribuição. Desta forma, se temos um
  equipamento elétrico, simplesmente o conectamos na tomada para que ele receba
  energia. O Grid Computacional ({\em The Computational Grid}), portanto, seria
  uma rede na qual o individuo se conecta para obter {\em Serviços
  Computacionais} que agregam recursos sob demanda (ex.: ciclos, armazenamento,
  software, periféricos, etc). A Figura~\ref{fig:grid} ilustra esta idéia.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=GridVision.eps,width=121mm,height=80mm}
\insimg{1}{imagens/GridVision.jpg}
\caption{Acesso transparente a serviços e recursos}
\label{fig:grid}
\end{center}
\end{figure}

Um sistema que forneça serviços computacionais sob demanda de forma transparente
é certamente desejável para várias instituições e aplicações. Note que, para
muita gente, a Internet é este sistema. De fato, para aqueles cujas necessidades
de processamento são satisfeitas por um computador pessoal, a Internet atende os
requisitos básicos de um Grid Computacional. Por exemplo, quando usamos {\em
 home banking}, nosso computador pessoal, uma série de roteadores e os
computadores do nosso banco se agregam sob demanda para nos fornecer um serviço
de forma transparente.

É importante esclarecer que não queremos, com o exemplo anterior, sugerir que um
Grid Computacional é o mesmo que a Internet. De uma certa forma, o Grid é a
evolução da Internet. A idéia é que {\em qualquer} serviço computacional possa
ser obtido no Grid, e que se possa agregar automaticamente vários serviços mais
simples, gerando um um serviço mais sofisticado. Voltando ao nosso exemplo de
{\em home banking}, este serviço é pensado para viabilizar o acesso de um humano
(um cliente do banco) à seus dados bancários. É muito complicado usar o serviço
em outros contextos, como parte de uma aplicação maior, que por exemplo acesse
os dados bancários na preparação do imposto de renda.

Grids Computacionais nasceram da comunidade de Processamento de Alto Desempenho,
motivada pela idéia de se utilizar computadores independentes e amplamente
dispersos como plataforma de execução de aplicações paralelas
\cite{foster-gridbook}. Porém, com a evolução da pesquisa sobre Grids
Computacionais e tecnologias utilizadas pela indústria para com\-pu\-ta\-ção
distribuída, houve naturalmente uma convergência entre o mundo acadêmico e
empresarial. Assim, a idéia é prover uma infraestrutura que viabilize serviços
sob demanda, permitindo uma maior colaboração entre várias instituições, através
do compartilhamento de seus serviços e recursos, e utilizando mecanismos que
facilitem a interoperabilidade.

Os atrativos desta idéia incluem a possibilidade de fornecimento de {\em
  qualquer} serviço computacional sob demanda, o qual pode ser composto
  dinamicamente por outros serviços e agregar recursos localizados em várias
  instituições distintas e geograficamente dispersas. Além disso, os recursos
  podem ser alocados em uma quantidade enorme (e.g. centenas de milhares de
  computadores conectados via Internet) e por um custo muito menor do que
  alternativas tradicionais (baseadas em supercomputadores paralelos). 

Um aspecto importante, que deve ser considerado, é o fato de mesmo havendo a
  convergência entre tecnologias para alto desempenho e da indústria, existe uma
  leve diferença entre Grids que fornecem e que não fornecem um {\em serviço de
  execução remota}. Esse serviço é fundamental para a comunidade de alto
  desempenho, uma vez que permite a execução de aplicações paralelas no
  Grid. Mas, é concebível imaginar Grids mais comerciais, onde o foco é o acesso
  e composição de serviços sob demanda, que funcionem perfeitamente bem sem
  disponibilizar o serviço de execução remota. 

O serviço de execução remota é crucial porque ele introduz importantes desafios
para infraestrutura do Grid. Os Grids que fornecem execução remota tendem a ser
mais complexos, pois ao permitir uma maior flexibilidade aos clientes do
serviço, que podem {\em converter} o serviço de execução remota em {\em
  qualquer} serviço, deve-se preocupar com questões como segurança (ex.: como
proteger o recurso de aplicações maliciosas?) e escalonamento (ex: que serviço
de execução é mais adequado para a aplicação?). 

Neste texto, usaremos {\em Grids de Serviços} quando estivermos tratando
questões pertinentes a qualquer Grid, disponibilize ele o serviço de execução
remota, ou não. Usaremos {\em Grids para Alto Desempenho} quando estivermos
tratando das questões adicionais que são introduzidas pelo serviço de execução
remota. Assim, nesta nossa terminologia, todo Grid para Alto Desempenho é um
Grid de Serviços, embora o contrário não seja necessariamente verdade.

Outra forma de ver Grids é encará-los como plataformas de computação
distribuída. Há várias plataformas tradicionais de computação distribuída, seja
de propósito mais comercial (CORBA, DCOM, etc), seja de propósito mais técnico
(clusters, supercomputadores paralelos). Para esclarecer um pouco mais a
diferença entre os Grids e outras plataformas de computação distribuída, podemos
citar algumas características que são intrínsecas aos Grids. De modo geral, os
Grids são mais distribuídos, diversos e complexos que outras
plataformas. Aspectos que evidenciam esta distribuição, diversidade e
complexidade são:

\begin{itemize}

  \item {\em Heterogeneidade}: Os componentes que formam a infraestrutura tendem
  ser extremamente heterogêneos. Ou seja, é importante ter em mente que qualquer
  solução para Grids Computacionais deverá lidar com recursos de várias
  gerações, softwares de várias versões, instrumentos e serviços dos mais
  variados tipos. 

  \item {\em Alta dispersão geográfica}: Essa característica se refere a escala
  que um Grid pode atingir. Nesse sentido, Grids podem ter escala global,
  agregando serviços localizados em várias partes do planeta.

  \item {\em Compartilhamento}: Em contraste com soluções {\em space-shared}, um
  Grid não pode ser dedicado a uma aplicação de forma exclusiva por um
  determinado período de tempo. Isso tem impacto no desenvolvimento de
  aplicações que executam sobre a infraestrutura de um Grid Computacional.

  \item {\em Múltiplos domínios administrativos}: Grids congregam recursos de
  várias ins\-ti\-tu\-i\-ções. Sendo assim, além da heterogeneidade mencionada
  anteriormente, é possível tam\-bém a existência de várias políticas de acesso e
  uso dos serviços, de acordo com as diretrizes de cada domínio que faz parte do
  Grid.
 
  \item {\em Controle distribuído}: Tipicamente não há uma única entidade que
  tenha poder sobre todo o Grid. Isso é um reflexo da dispersão dos componentes
  do Grid, pois cada instituição pode implementar sua política em seus recursos
  locais, mas não interfere diretamente na implementação de políticas no acesso
  aos serviços de outras instituições participantes. 

\end{itemize}

Note que esta discussão propõe um conceito e não uma definição para Grid
Computacional. Uma plataforma de fornecimento de serviços computacionais que
apresenta as características acima listadas certamente é um Grid. Contudo, a
ausência de alguma das características não deve automaticamente desqualificar
uma determinada plataforma como Grid. Por outro lado, o leitor deve estar atento
que o termo Grid Computacional pode ser usado tão e somente como ferramenta de
marketing~\cite{foster-whatis}. Devido a sua popularidade e a seu impacto
positivo, o termo {\em Grid Computing} tem sido utilizado de forma muito
liberal, como no passado outros termos já foram (como: Orientação a Objetos,
Sistemas Abertos, Downsizing, Reengenharia, Internet/Intranet/Extranet, entre
outros). 

Portanto, com o objetivo de desmistificar e posicionar os esforços atuais na
con\-cre\-ti\-za\-ção da visão original dos Grids Computacionais, discutiremos vários
aspectos importantes dos Grids de Serviços, e também das questões particulares
dos Grids para Alto Desempenho, que incluem serviços de execução remota.

Este texto está organizado da seguinte forma: na sessão~\ref{sec:servico}
apresentamos os Grids de Serviços, suas principais características, benefícios,
desafios que tais características sugerem e os investimentos de padronização. Na sessão~\ref{sec:alto} serão apresentados as questões exclusivas a Grids para
Alto Desempenho, que envolvem o desenvolvimento de um ambiente de execução de
aplicações paralelas em escala global. Na sessão~\ref{sec:estudo} faremos um
estudo de caso com algumas soluções para Grids Computacionais. Finalmente, na sessão~\ref{sec:future} concluiremos uma breve discussão sobre as tendências
em Grids Computacionais.
\clearpage

\section{Grids de Serviços}
\label{sec:servico}
%\cutname{gridsdeservicos.html}

Antes de se iniciar uma discussão sobre aspectos relacionados a Grids de
Serviços é necessário definir o que é um serviço. Na teoria econômica, {\em um
  serviço é uma mercadoria imaterial provida por uma entidade legal (provedor)
  para satisfazer as necessidades de outra entidade
  (cliente)}~\cite{service-composition}. 

Utilizando essa definição como analogia, consideramos como {\em serviço
  computacional} qualquer recurso (ou outro serviço) que possa ser acessado
remotamente e descrito através de uma interface (por um provedor), a qual pode
ser interpretada de forma automática (por um cliente). Desta forma, tudo pode
ser considerado como serviço, desde que exista a possibilidade de se criar uma
abstração que forneça essa interface. 

Neste capítulo discutiremos as tecnologias que permitem o desenvolvimento de
infraestruturas baseadas em serviços computacionais, bem como aspectos
importantes para a implementação dessas infraestruturas. Em seguida, abordaremos
também padrões emergentes para Grids de Serviços.

\subsection{Acesso a Serviços}
\label{sec:acesso}

De modo geral, a idéia por trás de uma arquitetura baseada em serviços
computacionais não é uma novidade. Ou seja, o grande interesse atual da
comunidade científica e da indústria por arquiteturas orientadas a serviços, bem
como o crescimento de esforços nessa área se deve, em grande parte, pelo sucesso
e amplo uso de Web Services~\cite{andrew-predicts,joo-survey}.

Portanto, é possível citar várias tecnologias anteriores a Web Services, que em
sua essência forneciam mecanismos para a criação de arquiteturas baseadas em
serviços. Por exemplo, em um sentido amplo, podemos considerar {\sc
  corba}~\cite{corba-site} e {\sc rmi} ({\em Remote Method
  Invocation})~\cite{rmi-spec} como tecnologias que permitem a construção de
infraestruturas de computação distribuída baseadas em serviços. Todavia,
aspectos como a ampla dispersão de recursos, falta de controle central e vasta
diversidade de clientes, as quais são características intrínsecas dos Grids,
introduzem um requisito que se torna fundamental: {\em interoperabilidade}. 

Em {\sc rmi} o provedor do serviço (um objeto remoto) requer, invariavelmente,
que seu cliente, não só seja Java, como também conheça antecipadamente (em tempo
de compilação) qual é sua interface. Para tornar um serviço acessível, o
provedor deve registrá-lo no {\em {\sc rmi} registry}~\cite{rmi-spec}. O serviço
é identificado e incluído em um catálogo mantido pelo registro. Do outro lado, o
cliente usa uma {\sc url} para acessar o registro e obter uma referência para um
dos serviços publicados em seu catálogo. O acesso ao serviço é feito usando a
referência obtida através do {\em {\sc rmi} registry}. A Figura~\ref{fig:rmi}
ilustra o acesso a um serviço usando {\sc rmi}.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=rmi.eps,width=51mm,height=60mm}
\insimg{1}{imagens/rmi.png}
\caption{Acessando um serviço usando {\sc rmi}}
\label{fig:rmi}
\end{center}
\end{figure}

Ao contrário de {\sc rmi}, {\sc corba} oferece maior interoperabilidade entre
clientes e provedores. Isso é possível pois serviços {\sc corba} são descritos
através de uma linguagem de descrição ({\em Interface Definition Language} -
{\sc idl}), que é independente da linguagem em que o serviço e cliente são
implementados. Esse aspecto torna {\sc corba} mais flexível que {\sc rmi}, pois
permite que o cliente e o serviço sejam implementados em linguagens
diferentes. Por exemplo, podemos ter um cliente desenvolvido em C++ e um
serviço escrito em Java.

Em {\sc corba}, um serviço é acessado de forma semelhante a {\sc rmi}. A
diferença substancial está na existência de uma entidade chamada {\em Object
  Request Broker} ({\sc orb}). A Figura~\ref{fig:corba} ilustra a operação de acesso a um serviço na plataforma {\sc corba}. Note que o {\sc orb} é responsável por
prover transparência no acesso do cliente ao serviço. Assim, tanto a localização
e implementação do serviço, quanto do cliente tornam-se transparentes para
ambos. Essa transparência na localização torna-se viável pelo uso do protocolo
{\sc iiop} ({\em Internet Inter Orb Protocol}), que provê o transporte das
invocações do cliente ao serviço. 

\begin{figure}[htb]
\begin{center}
%\epsfig{file=diagram-orb_to_orb.eps,width=88mm,height=37mm}
\insimg{1}{imagens/diagram-orb_to_orb.png}
\caption{Acessando um serviço usando {\sc corba}~\cite{omg-site}}
\label{fig:corba}
\end{center}
\end{figure}

Apesar das vantagens de {\sc corba}, alguns autores defendem que {\sc corba}
falhou na garantia de interoperabilidade entre os {\sc orb}s, o que tornaria a
plataforma mais amplamente utilizada. O argumento é que a competição entre os
desenvolvedores de {\sc orb}s se tornou acirrada acarretando problemas de
interoperabilidade~\cite{corba-reincarnation}.

Por outro lado, Web Services surgiu como uma nova tecnologia para computação
distribuída, que aproveitou vários padrões já bem estabelecidos como seu
alicerce. O primeiro, e talvez maior, contraste entre Web Services e {\sc corba}
é a camada de transporte utilizada por cada uma das plataformas. Enquanto {\sc
  corba} é baseado no protocolo {\sc iiop}, Web Services aproveita o protocolo
{\sc http} para envio de mensagens entre cliente e provedor. A Figura~\ref{fig:ws} ilustra
como ocorre a comunicação entre o cliente e um Web Service. Note que a interface
do serviço é ``descoberta'' em tempo de execução. Após obtenção da referência
para o serviço, o cliente pode iniciar a comunicação com o serviço através do
envio de mensagens.  

\begin{figure}[htb]
\begin{center}
%\epsfig{file=ws_interaction.eps,width=88mm,height=53mm}
\insimg{1}{imagens/ws_interaction.png}
\caption{Interação entre cliente e provedor (Web Services)~\cite{gt3-tutorial}}
\label{fig:ws}
\end{center}
\end{figure}

\subsection{Descoberta de Serviços}
\label{sec:descoberta}

Apesar de ser possível que clientes acessem serviços diretamente (sem envolver
um ca\-tá\-lo\-go), permitir que os serviços sejam descobertos dinamicamente é
fundamental para construir uma infraestrutura de serviços sob demanda. 

Sendo assim, em Grids computacionais é fundamental que seja possível descobrir
os serviços existentes em uma infra-estrutura que podem atender a demanda de uma
determinada aplicação. A idéia é que um serviço de descoberta funcione como as
páginas amarelas de um catálogo telefônico, que permitem os usuários da rede
telefônica encontrarem prestadores de serviços, a partir de alguns critérios,
como classificação da atividade, localização do estabelecimento e outras
informações divulgadas no catálogo.

Em sistemas {\sc corba} por exemplo, o serviço de descoberta se chama
Trader~\cite{corba-site}. Ele possui o cadastro dos objetos distribuídos do
sistema com suas respectivas propriedades, e permite que qualquer objeto
consulte este cadastro para encontrar objetos cujas propriedades atendam um
determinado critério de pesquisa.

Se em um sistema {\sc corba}, restrito a uma única organização, um serviço de
descoberta é importante, o que dizer de sistemas em Grid, que executam em um
ambiente multi-institucional. Eles são fundamentais para que seja possível
compartilhar recursos e serviços computacionais em escala global. No contexto da
Computação em Grid, os recursos compartilhados podem ser ciclos de CPU, espaço
em disco, software, sensores, dentre outros, que podem tornar-se acessíveis na
rede como Web Services~\cite{webservices-spec}.

Neste sentido, existem várias propostas de se construir um serviço de descoberta
de Web Services. O serviço de descoberta mais discutido e incorporado à
arquitetura {\sc wsrf}~\cite{wsrf-spec} é do serviço {\sc uddi} (Universal
Description, Discovery, and Integration)~\cite{uddi-org}, já adotado por vários
produtos voltados para a tecnologia de Web Services, de grandes empresas como
Sun Microsystems, Microsoft e Oracle. O {\sc uddi} é ele mesmo um Web Service
que permite a formação de um catálogo global de todos os Web Services
compartilhados na Internet. Este catálogo é organizado em nós e registros. Um nó
é um servidor {\sc uddi} onde estão os dados dos serviços cadastrados. Um
conjunto de nós é chamado de registro, e cada nó só pode pertencer a um único
registro.

Um registro pode ser privado, público ou afiliado. Os registros privados, ou
corporativos, são aqueles que guardam informações de Web Services internos de
uma empresa, protegido por um firewall, que devem ter seu acesso restrito às
aplicações da empresa. Já os registros afiliados compartilham e trocam seus
dados de forma controlada com outros registros, baseado em acordos entre as
instituições envolvidas. Seus Web Services estão disponíveis apenas a usuários
autorizados. Um exemplo de registros afiliados é o de Web Services sendo
utilizados por aplicações de empresas de uma holding. Cada empresa poderia ter
seu próprio registro e eles juntos formarem um grupo de registros afiliados,
permitindo que as aplicações de cada empresa localizasse os serviços umas das
outras. Há ainda os registros públicos que, como o próprio nome sugere, guardam
informações sobre Web Services que podem ser acessados livremente na Web. Os
dados mantidos pelos registros públicos podem ser compartilhados ou transferidos
livremente entre eles. Um exemplo de um registro público é o UBR ({\sc uddi}
Business Registry), hoje estruturado em quatro nós, sob responsabilidade das
empresas IBM, Microsoft, NTT Communications e SAP. Qualquer entidade pode
publicar ou consultar serviços nesses nós, gratuitamente. O UBR está para os Web
Services assim como o Google está para as páginas Web. O consumidor de serviços
que quiser localizar serviços na rede, provavelmente terá mais sucesso em sua
busca se consultar o UBR. Igualmente, o provedor que quiser ter seus serviços
encontrados terá que publicá-los no UBR.

%Não apenas serviços podem ser cadastrados e consultadas no {\sc uddi}. Também as
%entidades provedoras ou consumidoras dos mesmos. Isso favorece a integração
%entre elas, assim como enriquece a descrição dos serviços catalogados.

No {\sc uddi}, cada Web Service tem cadastrado um documento WSDL (Web Service
Description Language, baseado em XML) que descreve o serviço oferecido,
fornecendo informações que ajudam a localizá-lo no catálogo, assim como
estabelecer a forma correta de invocá-lo. O cadastro e a consulta deve ser feito
pelas aplicações através de APIs que se comunicam com os nós centrais utilizando
o protocolo SOAP.

Alguns trabalhos criticam a natureza centralizada do {\sc uddi}, dizendo que,
apesar de ser adotado como padrão na arquitetura {\sc wsrf}, ele não oferece uma
solução eficiente, escalável e tolerante a falhas como serviço de descoberta de
Web Services, da forma como vem sendo implementado. Eles argumentam que, por ser
centralizado, o {\sc uddi} apresenta baixo desempenho na atualização e consulta
dos registros, que essa degradação tende a ser maior quanto maior for a
quantidade de serviços catalogados e que é um ponto único de falha.

Uma alternativa ao {\sc uddi} é o {\sc wspds} (Web Service Peer-to-peer
Discovery Service)~\cite{kashani-wspds}. O {\sc wspds} baseia-se no fato de que os Web Services podem formar uma rede peer-to-peer, onde os peers se conhecem e podem
trabalhar de forma cooperativa, para atender as consultas. A idéia é que quando
um peer precise realizar uma consulta na rede, ele a repasse primeiramente
a seus peers conhecidos. Estes por sua vez, propagam a consulta aos peers de sua
própria lista, até um limite definido por contadores de propagações contido nas
mensagens trocadas. Cada peer que recebe a mensagem, realiza a consulta em
sua lista local e retorna os resultados positivos para o peer original da
consulta, que é entregue ao executor da consulta. Esse protocolo é empregado por
aplicações populares como o Gnutella~\cite{gnutella-site}, na consulta de
arquivos compartilhados por seus usuários.

O {\sc wspds} traz algumas vantagens e desvantagens em relação ao {\sc
  uddi}. Ele é de fato uma solução mais tolerante a falhas, já que não possui
  pontos únicos de falha. Não há servidores, responsáveis por atender às
  consultas por serviços. A escalabilidade é também um ponto forte seu, já que o
  aumento da quantidade de serviços não influencia o desempenho das
  consultas. No entanto, não há uma garantia de que um serviço que atenda aos
  critérios de uma consulta seja localizado. Um resultado de consulta negativo
  não necessariamente significa a ausência de serviços na rede que satisfaçam os
  critérios de pesquisa. Pode acontecer que os peers que participam da
  pesquisa não tenham contato com o serviço que atende à consulta.

Uma alternativa híbrida entre as duas abordagens é a de federações de registros
{\sc uddi}~\cite{uddi-evolution}. A idéia é fazer com que os registros estejam
conectados entre si, em uma rede peer-to-peer. Desta forma, quando uma consulta
for feita a um registro e este não puder atendê-la, ele repassará a mesma
consulta a outros registros, e assim sucessivamente, de forma semelhante a como
ocorre no {\sc wspds}. Cada registro realizará a consulta em seus próprios nós e
devolverá ao registro original da consulta os resultados, que serão entregues ao
executor da consulta. Esta abordagem foi originalmente adotada pelo serviço
Trader do {\sc corba}. Ela aumenta a robustez, tolerância a falhas, eficiência e
escalabilidade do serviço de descoberta. A versão 3.0 do {\sc uddi} já fornece
suporte para múltiplos registros e permite a formação das federações. Com o
crescimento esperado do uso de Web Services e conseqüentemente do serviço {\sc
  uddi}, este parece ser o caminho natural de evolução do serviço de
descoberta. 

\subsection{Autenticação e Autorização}

Na Seção~\ref{sec:acesso} descrevemos como ocorre o acesso a serviços usando
várias tecnologias para computação distribuída. É importante ressaltar que
apresentamos uma simplificação da realidade. Pois, devido à ampla distribuição e
existência de múltiplos domínios administrativos, o acesso aos recursos que
compõem um Grid não é tão simples.

Quando comparamos o Grid com outras plataformas fica claro que a ampla dispersão
de serviços e clientes cria a necessidade de um maior controle sobre o acesso
aos serviços e recursos. Por exemplo, em uma rede local, ao efetuar login no
sistema, o usuário é identificado e autenticado, em geral, para todos os
recursos conectados e serviços disponíveis na rede. Pois, normalmente se mantém
um cadastro de usuários que é válido para toda a rede.

Já em Grids, é necessária uma forma de acesso para cada recurso (ou subconjunto
de recursos, quando estes compartilham do mesmo cadastro de
usuários). Obviamente, tal forma de acesso tem que oferecer garantias sobre
autenticação dos usuários, caso contrario os administradores de sistema não
serão simpáticos à idéia de permitir que usuários de outros domínios tenham
acesso aos recursos locais através dos serviços presentes naquele domínio
administrativo.

As iniciativas atuais de Grids têm tratado esse problema através do uso de
esquemas baseados em chaves pública e privada, bem como certificados
digitais. Desta forma, cada domínio administrativo pode manter sua política
local de autenticação e autorização, e exporta um serviço que cuida da
autenticação e autorização do acesso de clientes externos aos seus serviços.

Como veremos em mais detalhes na Seção~\ref{sec:globus} e na
Seção~\ref{sec:ourgrid}, algumas infraestruturas possuem uma camada que fornece
uma infraestrutura de segurança para que seja possível autenticar e autorizar o
acesso e uso de serviços do Grid, enquanto outras usam certificados digitais,
não apenas para autenticar usuários, mas também para prover comunicação segura
entre os clientes e os serviços.

\subsection{Privacidade de Dados}

Além das demandas por segurança dos provedores de serviços, os clientes desses
serviços também impõem necessidades de segurança. Logo, alguns clientes requerem
privacidade no tratamento dos seus dados enviados para os serviços. Desta forma,
é desejável que apenas o cliente e o serviço que recebe os dados tenham acesso a
eles. Várias aplicações necessitam esse nível de privacidade. Garantir esse
aspecto é algo desafiador em um ambiente amplamente distribuído e dinâmico como
o Grid.

A necessidade de proteção dos dados existe por dois motivos. O primeiro se
refere a possibilidade de acesso não autorizado a informações confidenciais. O
segundo aspectos, está relacionado a possibilidade de sabotagem, onde outra
aplicação modifica os dados a serem processados a fim de manipular os resultados
que serão obtidos com aquela computação.

A Entropia~\cite{entropia-site} provê mecanismos de criptografia para garantir a
segurança dos dados da aplicação nos recursos do Grid. Assim, apenas o
proprietário do dado armazenado poderá acessar e manipular os dados usando sua
chave de criptografia~\cite{entropia-article}. O problema é que é possível que
alguém possa modificar o código da Entropia para obter as chaves armazenadas por
eles.

Assim, ainda existem muitos problemas em aberto nessa área. Hoje, instituições
que necessitam de um serviço de execução distribuído e têm como requisito
principal privacidade não utilizam uma infraestrutura tão dispersa quanto o
Grid. Essas aplicações executam em ambientes controlados e proprietários onde a
privacidade pode ser garantida. Um exemplo disso foi a infraestrutura montada
pela HP para prover a renderização das imagens do filme Sherek
2~\cite{shrek-hp}.

\subsection{Composição de Serviço}

Em nossa sociedade, estamos bem acostumados com a prestação de serviços por
parte de empresas, profissionais e governo. Muitas vezes, para executar um
serviço, um prestador de serviço torna-se cliente de outros prestadores, sem que
seus clientes tomem conhecimento disso. Uma agência de turismo, por exemplo,
vende pacotes de viagem e para prestar este serviço, contrata serviços de
companhias aéreas, centrais de intercâmbio estudantil, hotéis, empresas de
aluguel de carro, etc. Para o cliente que compra o pacote, o serviço é prestado por uma única entidade. É como se a venda da passagem aérea, de quartos
em hotéis, aluguel de carro, fossem feitos pela própria agência de
turismo. Todavia, é muito difícil uma agência de viagens se estruturar e
funcionar, tendo que ser responsável por tantas atividades, que não são sua
atividade fim. O serviço torna-se mais caro e complexo de ser administrado. A
estratégia adotada é geralmente terceirizar estas atividades. Assim, a
venda do pacote de viagem torna-se uma {\em composição de serviços} prestados
por diversas entidades.

Da mesma forma, em Grids Computacionais, os serviços podem ser compostos por
outros serviços. A composição de serviços traz uma série de benefícios para a
computação distribuída. Os dois principais são: $i)$ Abstração da complexidade
do serviço para o cliente; $ii)$ Reutilização das funcionalidades implementadas
por outros serviços.

Para o cliente, quanto mais complexo for o serviço, menos envolvido ele desejará
estar. No exemplo citado anteriormente, sem o trabalho das agências de turismo,
o preparo de uma viagem implicará em muito mais trabalho para o cliente. A venda
de pacotes turísticos simplifica muito o trabalho dos que pretendem tirar
férias. Da mesma forma, no mundo da computação, quanto mais compostos forem os
serviços, mais simples e alto nível deve ser programação das aplicações
clientes. 

O segundo aspecto positivo da composição de serviço é a reutilização de
código. Um serviço já desenvolvido e disponível no sistema rede pode ser usado
na composição de novos serviços. Desta forma, seu código não tem que ser
reimplementado. Um exemplo real são os Web Services fornecidos pela Receita
Federal, que permitem consulta e validação de {\sc cpf} e {\sc cnpj}. Estas
funcionalidades estão presentes em diversas aplicações por todo o país. Como
serviços, elas podem ser utilizadas por essas diversas aplicações, evitando que
sejam implementadas novamente.

Entretanto, a composição traz também desafios. Um deles é como um serviço
composto pode garantir qualidade, uma vez que ele não é o responsável direto por
executar todas as suas etapas. Como no mundo real, para os clientes que usam um
serviço, é como se ele fosse único, prestado por um único provedor. No exemplo
usado anteriormente, a responsabilidade por atender aos requisitos do cliente
que compra o pacote de viagem é do provedor do serviço. O serviço da agência
teria que atender os requisitos de segurança, tempo de processamento, limites de
custo informados pelo cliente, para o qual, a composição do serviço invocado é
transparente.

Para a especificação apropriada de serviços compostos, precisamos de modelos que
definam as várias características da composição. Ou seja, a identificação dos
possíveis componentes, quando, como e em que condições serão usados, regras para
seu funcionamento, dentre outras. Assim, um modelo de composição possui as
seguintes dimensões: 

\begin{itemize}

  \item {\em Modelo de componentes}: define a estrutura dos componentes que
  fazem parte da composição; 

  \item {\em Modelo de orquestração}: especifica a ordem em que cada componente
  deverá ser acionado, e sobre quais condições; 

  \item {\em Dados e modelo de acesso aos dados}: especifica a estrutura dos
  dados usados na composição, bem como a forma de acesso a eles; 

  \item {Modelo de seleção de serviço}: especifica como o usuário pode
  selecionar cada serviço, e o papel que cada componente desempenha na
  composição; 

  \item {Transações}: especifica o tratamento de transações pela composição - o
  que deve ser feito quando uma falha ocorre durante a execução de uma
  transação.
 
\end{itemize}

Na tentativa de suprir a demanda por linguagens e ferramentas especialmente
voltadas para a composição de serviços, vários trabalhos foram desenvolvidos até
então, por exemplo, XLANG~\cite{thatte-xlang}, WSFL~\cite{leymann-wsfl} e
BPEL4WS~\cite{bpel4ws}. Apesar do alto nível da especificação e riqueza de
detalhes que estas linguagens permitem alcançar nas es\-pe\-ci\-fi\-ca\-ções, elas têm
sofrido várias críticas da comunidade.

A principal crítica diz respeito ao fato de que ao especificar a composição de
serviços, é necessário conhecer antecipadamente todos os serviços que fazem
parte da composição, bem como a ordem e condições em que cada tarefa deve ser
executada. Isto torna impossível montar novas composições em tempo de execução,
automaticamente. Isto abre uma lacuna na área, criando uma demanda por modelos
de descrição e ferramentas mais ricos, para que se possa superar este obstáculo,
e oferecer serviços cada vez mais complexos e dinâmicos. 

\subsection{Disponibilização de Serviços}

Para que Grids sejam úteis, é preciso que eles existam, é preciso criá-los. Ou
seja, após ser possível descobrir os serviços, eles devem ser agregados para
criar uma infraestrutura de serviços computacionais, que permita a execução de
aplicações. Esta sentença é bastante óbvia. Contudo, ela levanta alguns
problemas técnicos não-triviais. Suponha que duas instituições A e B decidem
formar um Grid, unificando seus recursos e fornecendo melhores serviços
computacionais a seus usuários. Porém, como incentivar domínios administrativos
a participarem do Grid com seus serviços e recursos? 

Suponha que $A$ tem mais que o dobro dos recursos de $B$. Um compartilhamento
igualitário seria prejudicial a $A$, que então relutaria em formar um Grid com
$B$. Por outro lado, assuma que $A$ não pode fornecer acesso a seus recursos
durante o expediente bancário (10:00 as 16:00). Como se pode perceber, o
contrato entre $A$ e $B$ para compartilhamento de recursos e construção de um
Grid comum pode ser algo bastante sofisticado. Tal sofisticação gera uma
pergunta óbvia de como as regras de compartilhamento acordadas serão
implementadas e policiadas.

Se a criação de um Grid entre duas instituições pode oferecer tal complexidade,
imagine a criação de Grids envolvendo centenas ou milhares de entidades. A
abordagem que vem sendo sugerida para este problema é a utilização de modelos
econômicos para guiar esse processo de criação de
Grids~\cite{buyya-economy,cirne-computational}. A idéia básica é
a construção de um mercado computacional onde as diversas entidades envolvidas
no Grid possam trocar recursos. O aspecto mais atraente desta abordagem é que
acordos de compartilhamento sofisticados não são mais necessários. Recursos são
comprados e vendidos de forma independente, sem um supervisor onisciente do
mercado. Desta forma, entidades podem decidir independentemente quando comprar
ou vender recursos. Inicialmente, a moeda utilizada será provavelmente algum
dinheiro virtual que daria apenas poder de compra de recursos
computacionais. Entretanto, é razoável imaginar que o câmbio entre este dinheiro
virtual e dinheiro real logo se torne possível, incentivando a criação de
empresas que forneçam serviços computacionais sob demanda.

É importante destacar três elementos que formam a base desta economia:
provedores de serviços, consumidores de serviços e os serviços propriamente
ditos. Note que provedor e consumidor são papéis que podem ser assumidos
concorrentemente. Abaixo listamos e discutimos brevemente alguns modelos
econômicos~\cite{buyya-grace}:

\begin{itemize}
       \item {\em Commodity Market}: Provedores divulgam de forma competitiva
       seus serviços e os respectivos preços. Consumidores decidem baseado no
       custo/benefício qual provedor irão contratar.

       \item {\em Posted Price Market Model}: Muito similar ao {\em Commodity
       Market}, a diferença consiste no tempo que dura a oferta de preços feita
       pelos provedores. Nesse caso, as ofertas duram mais tempo.

       \item {\em Bargaining Model}: Provedores e consumidores negociam preços
       dos serviços, onde cada um tenta maximizar o resultado de acordo com seus
       objetivos. Neste caso as negociações são entre pares
       Consumidor-Provedor. Sendo assim, os consumidores tomam a decisão
       (contratar ou não) baseado em seus objetivos locais.

       \item {\em Tender/Contract Net}: Uma espécie de licitação. Um convite de
       oferta parte do consumidor para vários provedores que respondem com seus
       preços e condições de serviço. O consumidor decide qual contratar fazendo
       a análise do custo do serviço e das condições de atendimento.

       \item {\em Auction}: Neste modelo os provedores enviam convites de oferta
       aos consumidores. Os consumidores pode modificar sua oferta (em
       incrementos positivos). A negociação finaliza quando os consumidores
       param de efetuar ofertas.

       \item {\em Bid based Proportional Resource Share}: Neste modelo a
       quantidade de recursos / ser\-vi\-ços é alocada aos consumidores de forma
       proporcional ao valor de suas ofertas.

       \item {\em Community/Coallition/Bartering Model}: A idéia básica deste
       modelo é a criação de um ambiente cooperativo de compartilhamento de
       recursos. Ou seja, provedores que contribuem terão garantida a
       possibilidade de consumir quando necessitarem. 

\end{itemize}

A seguir, apresentaremos estratégias usadas para incentivar a participação de
entidades no Grid. A idéia é promover a agregação de recursos de vários domínios
administrativos, com o intuito de formar um Grid que beneficie os clientes de
cada domínio.

\subsubsection{{\sc grace} - Grid Architecture for Computational Economy}

É desejável que uma solução para o problema de incentivo à participação no Grid
forneça flexibilidade no que se refere as políticas de compartilhamento de
recursos. Ou seja, é necessária a existência de mecanismos que garantam o
compartilhamento de recursos de forma escalável. Além disso, dever ser possível
para o cliente expressar seus requisitos, bem como os provedores expressarem as
condições de fornecimento serviço.

Assim, acompanhando a metáfora usada inicialmente baseada na idéia do {\em The
  Electric Grid}, que serviu para traçar os objetivos dos Grids Computacionais,
a aplicação de modelos econômicos também se baseia no fato que já existem
abordagens baseadas em leilão para o mercado de energia
elétrica~\cite{electric-trade}. 

Portanto, a introdução de modelos de compartilhamento mais sofisticados,
baseados em economia, promete uma infraestrutura mais flexível e poderosa para
o compartilhamento de recursos e construção de Grids. Um exemplo de investimento
nessa área de pesquisa é o {\sc grace} (GRid Architecture for Computational
Economy)~\cite{buyya-grace}. A arquitetura do {\sc grace} foi pensada levando em
consideração os requisitos que uma infraestrutura de economia computacional deve
preencher. Logo, inspirado pela idéia de mercados, os princípios de projeto da
arquitetura são:

\begin{enumerate}

    \item Um diretório onde seja possível publicar informações sobre as
    entidades que formam o Grid (i.e. consumidores e provedores), tal como
    descrito na Seção~\ref{sec:descoberta}.

    \item Modelos para o estabelecimento de valores para os recursos / ser\-vi\-ços.

    \item Esquemas de cotação e mecanismos de oferta de serviços.

    \item Modelos econômicos e protocolos de negociação de contratação de
    serviços

    \item Mediadores que atuam como reguladores e estabelecem valores para os
    recursos / serviços, criam moeda padrão e ajudam na resolução de impasses
    entre os negociadores.

    \item Mecanismos para contabilização, cobrança e pagamento.

\end{enumerate}

Para tanto, a arquitetura do {\sc grace} é composta dos seguintes componentes:
$a)$ Grid Resource Broker (e.g., Nimrod/G); $b)$ Grid Resource and Market
Information Server; $c)$ Grid Open Trading Protocols and API; $d)$ Trade
Manager; $e)$ Grid Trade Server. 

O {\em Resource Broker} funciona como um procurador do usuário (ou de sua
aplicação) perante ao Grid. Sendo assim, o Resource Broker desempenha atividades
que permitem a execução da aplicação do usuário atendendo seus requisitos
(e.g. menor preço pelo serviço de execução). Além disso, um aspecto importante é
que o Resource Broker exibe o Grid para o usuário como um conjunto unificado de
recursos, essa abstração facilita a visão do usuário sobre o ambiente. 

Certamente, o Resource Broker depende da existência de vários serviços. Por
exemplo, serviços de informação sobre os recursos que são oferecidos no Grid,
seus preços e condições de uso. Esse serviço é fornecido pelo {\em Grid Resource
  and Market Information Server}, o qual utiliza como base o serviço de
descoberta de serviços do Globus (i.e. {\sc mds}~\cite{globus-toolkit}).

Além de obter informação sobre serviços disponíveis e suas cotações, é
necessário que haja um padrão (um protocolo bem conhecido pelo cliente e pelo
provedor de serviços) para a negociação. Logo, a arquitetura do {\sc grace}
possui um conjunto de protocolos e uma API que define regras e o formato para
troca de comandos entre o cliente {\sc grace} (i.e. {\em Trade Manager}) e o
provedor do serviço ({\em Trade Server}).  

Vale mencionar que o {\em Trade Manager} é uma parte importante do Resource
Broker, pois tem o papel de guiar a seleção dos recursos que a aplicação
necessita para atingir seus objetivos. Por outro lado, o {\em Trade Server} é o
agente de negociação do lado do provedor, sua função é maximizar a utilização do
recursos e o lucro do provedor. 

Portanto, a negociação entre os Trade Managers (clientes) e os Trade Servers
(provedores) ocorrerá de acordo com algum modelo econômico. Uma das
implementações possíveis do {\sc grace} utiliza como {\em broker} o
Nimrod/G~\cite{buyya-nimrodg}. O modelo econômico implementado foi o {\em Posted
  Price Market Model} descrito anteriormente~\cite{buyya-grace}. Nesse caso, os
vários {\em Trade Servers} do sistema devem divulgar seus preços, de forma a
atrair consumidores, esperando que os {\em Trade Managers} requisitem o serviço,
tomando como base para escolha a comparação de preços entre os preços
divulgados.

\subsubsection{Rede de Favores}
\label{sec:rede}

Apesar ser bastante pertinente, a introdução de modelos econômicos a fim de
controlar o compartilhamento de recursos entre sites, um grande número de
aplicações, que igualmente necessitam de uma infraestrutura de recursos/serviços
computacionais de larga escala, não requerem um contrato tão forte entre
clientes e provedores, como as providas por uma arquitetura baseada em modelos
econômicos. Ao manter o foco neste tipo de aplicação, se torna possível
desenvolver uma solução prática que pode ser usada efetivamente por uma
comunidade de usuários.

Claramente, estamos apresentando um dilema entre ter uma infraestrutura de
escopo mais geral, porém mais complexa o que dificultaria sua implantação
efetiva, e uma infraestrutura mais simples, o que facilitaria sua implantação,
porém com um escopo mais restrito. Pensando nisso, foi desenvolvida a solução
OurGrid~\cite{ourgrid-site,andrade-ourgrid}. A idéia é ser uma solução simples
que permita a criação de Grids Computacionais que fornecem poder computacional
seguindo a política {\em best-effort}. O foco está em aplicações Bag-of-Tasks
(i.e. aquelas aplicações cujas tarefas são independentes), com essa redução de
escopo foi possível ter um Grid Computacional em produção~\cite{cirne-paua}. O
OurGrid é formado por três componentes: MyGrid Broker~\cite{cirne-mygrid},
OurGrid Peer~\cite{andrade-ourgrid} e uma solução de Sanboxing baseado no
Xen~\cite{xen-art}.

OurGrid explora a idéia de que um
Grid é composto de vários sites que têm o interesse em trocar {\em favores
  computacionais} entre si. Portanto, existe uma rede peer-to-peer de troca de
favores que permite que os recursos ociosos de um site seja fornecido para outro
quando solicitado. Para manter o equilíbrio do sistema, em uma situação de
contenção de recursos, sites que doaram mais recursos (quando estes estavam
ociosos) deverão ter prioridade junto à comunidade quando solicitar recursos. 

A Figura~\ref{fig:nof} ilustra a idéia da rede de favores, onde cada peer
controla um conjunto de recursos de um site. Ao surgir uma demanda interna por
recursos que o peer de um determinado site não consegue suprir, este {\sc
  peer} irá fazer requisições à comunidade. A idéia é que os peers utilizem um
esquema de prioridade baseado em quanto eles consumiram dos outros. Os
resultados mostram que haverá um compartilhamento justo de recursos entre os
peers~\cite{andrade-discouraging}.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=network.eps,width=147mm,height=93mm}
\insimg{1}{imagens/network.png}
\caption{Ilustração da arquitetura OurGrid~\cite{ourgrid-site}}
\label{fig:nof}
\end{center}
\end{figure}


\subsection{Padronização}

Nesta seção exploraremos um pouco mais a visão que motiva boa parte da pesquisa
sobre Grids Computacionais atualmente, orientação a serviços. Neste sentido,
faremos também um breve histórico sobre os padrões para arquiteturas baseadas em
{\em Grid Services} e qual o estado atual desses esforços. 

\subsubsection{A visão}

A experiência prática adquirida no desenvolvimento dos Grids de alto desempenho
tornou possível identificar os problemas que dificultam a implantação de uma
infraestrutura com esta escala e complexidade. A questão central que deve guiar
o desenvolvimento de tecnologias para Grids Computacionais pode ser entendida
como sendo a integração de recursos e serviços distribuídos de forma
transparente e eficiente. Assim, foi identificado que este requisito motiva
tanto a comunidade científica como a indústria. 

Portanto, do lado acadêmico, a crescente necessidade de cooperação científica
entre grupos geograficamente distribuídos, através do compartilhamento de
recursos e serviços, do outro lado a indústria que tem como necessidade a
integração de sistemas comerciais. Essas demandas impulsionaram a convergência
de tecnologias de ambas as comunidades.  

Como resultado, os Grids evoluíram para utilizar uma abordagem orientada a
serviços baseado em padrões e tecnologias para Web Services. Partindo de um
conjunto de serviços básicos, como autenticação e transferência de dados, a
idéia é a construção de Grids que forneçam de serviços sob demanda. 

\subsubsection{{\sc ogsa}/{\sc ogsi}/Globus 3.x}
\label{sec:gt3}

No intuito de realizar a visão da orientação a serviços, houve um convergência
de tecnologias da área de computação de alto desempenho e de padrões bem
consolidados pela indústria, isso ocorreu através da união de tecnologias e
conceitos Grids com {\em web services}~\cite{wsca-site}. A partir disto foi
definida uma arquitetura de serviços básicos para a construção de uma
infraestrutura de Grids Computacionais baseados em Serviços. Esta arquitetura
foi denominada {\em Open Grid Services Architecture} ({\sc
  ogsa})~\cite{foster-physiology,ogsa-site}. 

A definição do {\sc ogsa} contempla a idéia de interconexão de sistemas e a
criação de ambientes virtuais multi-institucionais. Além disso, os recursos que
podem ser agregados ao Grid são representados por serviços e estes serviços são
chamados de {\em Grid Services}~\cite{foster-physiology}. Os {\em grid services}
são essencialmente {\em web services} que seguem convenções estabelecidas na
especificação da {\sc ogsa} e suportam interfaces padronizadas para garantir
algumas operações adicionais, como gerenciamento do ciclo de vida do serviço. 

As interfaces padrões definidas pelo {\sc ogsa} facilitam a virtualização
de recursos e serviços. Isso possibilita o uso de vários tipos de recursos de
forma transparente. Outra vantagem da virtualização é que interfaces padrões
permitem um baixo acoplamento entre o cliente e o provedor do serviço. Esse
baixo acoplamento facilita a mudança na implementação dos serviços sem causar,
necessariamente, mudanças na implementação do cliente, bem como o inverso.

Após a definição do modelo da arquitetura e identificação de serviços básicos
através do padrão {\sc ogsa} foi necessária a especificação do comportamento
desses serviços. Sendo assim, o passo seguinte foi a especificação dessa
infraestrutura serviços básicos, no intuito de permitir a implementação do
modelo da arquitetura definida pela {\sc ogsa}. A nova especificação foi
denominada {\em Open Grid Services Infrastructure} ({\sc ogsi})~\cite{ogsi-spec}
e tem o objetivo de definir as interfaces básicas e os comportamentos de um {\em
  Grid Service}~\cite{ogsa-site}. {\sc ogsi} é a materialização da arquitetura
definida pelo padrão {\sc ogsa}, pois os serviços especificados servem como base
para construção dos Grids. Em termos práticos, a especificação {\sc ogsi}
define:

\begin{itemize}

  \item Um conjunto de extensões para a linguagem {\sc wsdl} (Web Service
  Description Language).
   
  \item Padrões de estrutura e operação, em {\sc wsdl}, para representação
  pesquisa e a\-tu\-a\-li\-za\-ção de dados sobre os serviços. 

  \item As estruturas {\em Grid Service Handle} e {\em Grid Service
  Reference} usados para referenciar um serviços.

  \item Formato para mensagens que indicam falhas, sem modificar o modelo de
  mensagens de falha da linguagem {\sc wsdl}.

  \item Conjunto de operações que permitem a criação e destruição de Grid
  Services. Esse conjuntos de operações devem fornecer destruição explícita de
  serviços, como também {\em garbage collection} (destruição implícita do
  serviço). 

  \item Conjunto de operações para criação e uso de coleções de Web Services por
  referência.

  \item Mecanismos que permitam notificação assíncrona, caso haja mudança em
  valores dos elementos de dados dos serviços. 

\end{itemize}

O {\em Globus Toolkit 3.0} ({\sc GT3})~\cite{globus-toolkit} forneceu a primeira
implementação da {\sc ogsi} $1.0$ em julho de 2003. No intuito de esclarecer
melhor o papel de {\sc ogsa}, {\sc ogsi} e Globus, Figura~\ref{fig:ogsa_ogsi}
ilustra como essas entidades se relacionam formando um cenário de padrões e
implementações de tecnologias para Grids de Serviço. 

\begin{figure}[htb]
\begin{center}
%\epsfig{file=ogsa_ogsi.eps,width=64mm,height=65mm}
\insimg{1}{imagens/ogsa_ogsi.png}
\caption{Relacionamento entre {\sc ogsa}, {\sc ogsi} e Globus~\cite{gt3-tutorial}}
\label{fig:ogsa_ogsi}
\end{center}
\end{figure}

Note, portanto, que {\em Grid Service} é um conceito central no relacionamento
destas tecnologias e padrões. Assim, {\sc ogsa} define Grid Services, {\sc ogsi}
especifica o comportamento de Grid Services, Web Services são estendidos para se
tornar Grid Services e Globus 3 implementa a especificação {\sc ogsi}. Além
disso, Globus provê serviços básicos necessários para a construção de serviços
de mais alto nível (e.g. serviços de autenticação via {\sc gsi}).

\subsubsection{{\sc wsrf}/Globus 4.x}
\label{sec:gt4}

Uma vez que toda a base de {\em Grid Services} surgiu das tecnologias para Web
Services, alguns aspectos da especificação {\sc ogsi} precisavam ser refinados
devido a evolução da arquitetura Web Services.

O principal ponto de crítica foram os mecanismos de endereçamento para os
serviços (i.e. {\em Grid Service Handler} e {\em Grid Service Reference}). Nesse
caso, {\em WS-Addressing} surgiu pra fornecer um mecanismo de endereçamento
independente da camada de transporte~\cite{ogsi-wsrf}.

Além disso, outras características de {\sc ogsi} precisavam ser modificadas para
acompanhar a evolução da tecnologia Web Service, melhorando assim a
especificação {\sc ogsi}. Assim, {\sc wsrf} ({\em Web Service Resource
  Framework}) é basicamente o resultado do refinamento de {\sc ogsi} no intuito
de aproveitar a existência dos novos padrões que surgiram para para Web Services
(e.g. WS-Addressing, WS-Notification) e assimilar a demanda da comunidade Web
Services. 

O primeiro efeito do refatoramento foi a divisão de {\sc ogsi} em várias
especificações separadas, porém agrupadas em uma família. A idéia é reduzir a
complexidade de uma especificação longa, que dificulta a adoção incremental de
funcionalidades. 

Outra medida importante foi a recuperação da compatibilidade com as ferramentas
existentes para XML e Web Services, pois {\sc ogsi} usa {\sc gwsdl}, a qual
provê acréscimos à {\sc wsdl} 1.1 que estarão disponíveis na {\sc wsdl}
1.2/2.0. Ao contrário de {\sc ogsi}, ao invés de estender a definição de {\em
  portType} WSDL 1.1, ou mesmo esperar pelo da nova versão {\sc wsdl} 2.0,
WS-Resource Framework utiliza puramente {\sc wsdl} 1.1, o que garante
compatibilidade com as ferramentas existentes para Web Services.

Alguns entusiastas da área de Web Services, em geral, argumentam que {\em Web Services não devem manter estado ou ter instâncias}. Ou seja, {\sc ogsi} modela um recurso que mantém estado como um Web Service que encapsula o estado do recurso. WS-Resource Framework modifica esse modelo para criar uma distinção explícita entre {\em serviço} e entidades que mantêm estado e são manipuladas através do serviço. Esta composição é denominada {\em WS-Resource} pelo padrão {\sc wsrf}, que introduz a idéia de recursos que mantêm estados e podem ser acessados através de Web Services via o uso convencional de WS-Addressing.

Portanto, em linhas gerais, a evolução de {\sc ogsi} obedeceu três fases de
forma incremental. A primeira, a introdução do conceito de {\em WS-Resource}. Em
seguida a divisão de funcionalidades em várias especificações melhorando a
compatibilidade com ferramentas usadas para Web Service.  Finalmente, uma
melhoria nos mecanismos de notificação.

O padrão {\sc wsrf} deve se materializar, de forma estável, através do
lançamento do Globus 4. Atualmente, Março de 2005, o Globus se encontra na
versão 3.9.5, que apesar de instável já incorpora várias das funcionalidades
contempladas no padrão {\sc wsrf}. Por exemplo, o {\sc gram} do Globus 3, será
substituído pelo {\sc WS-gram}, o qual segue as especificações definidas na
família de padrões {\sc wsrf}.
\clearpage

\section{Grids para Alto Desempenho}
\label{sec:alto}
%\cutname{gridsparaaltodesempenho.html}

Neste capítulo os Grids Computacionais são apresentados como uma plataforma de
e\-xe\-cu\-ção para aplicações paralelas. Sendo assim, faremos comparações com
plataformas de e\-xe\-cu\-ção convencionais. Em seguida definiremos quais são os tipos
de aplicações paralelas mais adequadas para executar em um Grid
Computacional. Finalmente, apresentaremos dois estudos de caso.

\subsection{Plataformas para Processamento Paralelo}
\label{sec:plataforma}

Uma aplicação paralela é composta por várias tarefas. As tarefas que compõem uma
aplicação paralela executam em vários processadores, caracterizando desta forma
o paralelismo da execução da aplicação e conseqüente redução no seu tempo de
execução. Os processadores usados por uma determinada aplicação constituem a
plataforma de execução da aplicação. 

Plataformas de execução de aplicações paralelas variam em diversos aspectos, dos
quais destacamos conectividade, heterogeneidade, compartilhamento, imagem do
sistema e escala. 

\begin{itemize}

\item {\em Conectividade} diz respeito aos canais de comunicação que interligam
  os processadores que compõem a plataforma de execução. Atributos que definem a
  conectividade de uma plataforma são a topologia, largura de banda, latência e
  compartilhamento. 

\item {\em Heterogeneidade} trata das diferenças entre os processadores, que
  podem ser de velocidade e/ou arquitetura.

\item {\em Compartilhamento} versa sobre a possibilidade dos recursos usados por
  uma a\-pli\-ca\-ção serem compartilhados por outras aplicações.

\item {\em Imagem do sistema} se refere à existência de uma visão única da
  plataforma, independente do processador sendo utilizado. Por exemplo, todos os
  processadores da plataforma enxergam o mesmo sistema de arquivos?

\item {\em Escala} estabelece quantos processadores tem a plataforma. 

\end{itemize}

Entender as diferenças entre plataformas é fundamental porque cada aplicação
paralela tem uma série de requisitos, que podem ser melhor ou pior atendidos por
uma dada plataforma. Em princípio, procuramos executar uma aplicação paralela em
uma plataforma adequada às características da aplicação. Por exemplo, considere
conectividade, um aspecto em que plataformas diferem
consideravelmente. Obviamente, para obter boa performance de uma aplicação
paralela cujas tarefas se comunicam e sincronizam freqüentemente, necessitamos
utilizar uma plataforma de execução com boa conectividade.

Podemos agrupar as plataformas de execução hoje existentes em quatro grandes
grupos: SMPs, MPPs, NOWs e Grids. SMPs (ou multiprocessadores simétricos) são
máquinas em que vários processadores compartilham a mesma
memória. Multiprocessadores possibilitam um fortíssimo acoplamento entre os
processadores e executam uma única cópia do sistema operacional para todos os
processadores. Portanto, eles apresentam uma imagem única do sistema e excelente
conectividade. Todavia, multiprocessadores apresentam limitações em
escalabilidade, raramente ultrapassando algumas dezenas de
processadores. Multiprocessadores são relativamente comuns no mercado e vão
desde máquinas biprocessadas Intel até grandes servidores como os da série HP
9000. A Figura~\ref{fig:smp} ilustra a arquitetura de um multiprocessador.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=multiprocessor.eps,width=54mm,height=34mm}
\insimg{1}{imagens/multiprocessor.png}
\caption{Arquitetura multiprocessada}
\label{fig:smp}
\end{center}
\end{figure}

MPPs (ou processadores maciçamente paralelos) são compostos por vários nós
(processador e memória) independentes,interconectados por redes dedicadas e
muito rá\-pi\-das. MPPs incluem supercomputadores paralelos como o IBM SP2 e Cray
T3E, como também clusters de menor porte montados pelo próprio
usuário. Tipicamente cada nó roda sua própria cópia do sistema operacional, mas
uma imagem comum do sistema é implementada através da visibilidade dos mesmos
sistemas de arquivo por todos os nós. O MPP é controlado por um escalonador que
determina quais aplicações executarão em quais nós. Ou seja, não se pode
utilizar um nó que não tenha sido alocado à aplicação pelo escalonador. Isto
possibilita dedicar partições (um conjunto de nós) às aplicações, permitindo que
estas não precisem considerar compartilhamento. Mas, uma vez que aplicações
executam em partições dedicadas, pode acontecer que não haja nós suficientes
para executar uma aplicação assim que ela é submetida. Neste caso, a aplicação
espera em uma fila até que os recursos que solicitou estejam disponíveis. A
Figura~\ref{fig:mpp} exemplifica a arquitetura de um MPP.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=mpparch.eps,width=156mm,height=60mm}
\insimg{1}{imagens/mpparch.png}
\caption{Arquitetura de um MPP}
\label{fig:mpp}
\end{center}
\end{figure}

{\sc NoW}s (ou redes de es\-ta\-ções de trabalho) são simplesmente um conjunto de
es\-ta\-ções de trabalho ou PCs, ligados por uma rede local. {\sc NoW}s são
arquiteturalmente semelhantes aos MPPs. Ambas plataformas são formadas por nós
que agregam processador e memória. Uma diferença entre {\sc NoW}s e MPPs é que
os nós que compõem uma MPP tipicamente são conectados por redes mais rápidas que
as que conectam os nós de {\sc NoW}s. Mas a principal diferença entre ambas
arquiteturas é que {\sc NoW}s não são escalonadas de forma centralizada. Isto é,
em uma {\sc NoW}, não há um escalonador para o sistema como um todo. Cada nó tem
seu próprio escalonador local. Como resultado, não há como dedicar uma partição
da {\sc NoW} a uma só aplicação paralela. Assim, uma aplicação que executa sobre
a {\sc NoW} deve considerar o impacto da concorrência por recursos por parte de
outras aplicações sobre sua performance. A Figura~\ref{fig:now} mostra
esquematicamente uma {\sc NoW}.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=nowarch.eps,width=85mm,height=50mm}
\insimg{1}{imagens/nowarch.png}
\caption{Arquitetura de uma {\sc NoW}}
\label{fig:now}
\end{center}
\end{figure}

Grids são o passo natural depois dos {\sc NoW}s no sentido de mais
heterogeneidade e maior distribuição. Os componentes de um Grid não se
restringem a processadores, podendo ser SMPs e MPPs como também instrumentos
digitais. Grids tipicamente não fornecem uma imagem comum do sistema para seus
usuários. Componentes do Grid podem variar drasticamente em capacidade, software
instalado, sistemas de arquivo montados e periféricos instalados. Além disso, os
componentes de um Grid tipicamente estar sobre controle de diferentes entidades
e, portanto, em domínios administrativos diversos. Conseqüentemente, um dado
usuário pode ter acesso e permissões bastante diversas nos diferentes
componentes de um Grid. Obviamente, o Grid não pode ser dedicado a um usuário,
embora seja possível que algum componente possa ser dedicado (um MPP, por
exemplo). É importante salientar que uma aplicação que executa sobre o Grid deve
estar preparada para lidar com todo este dinamismo e variabilidade da plataforma
de execução, adaptando-se ao cenário que se apresenta com o intuito de obter a
melhor performance possível no momento. A Figura~\ref{fig:gridarch}  exemplifica
um possível Grid, composto por um MPP e computadores de vários tipos conectados
via Internet. Note que um destes computadores realiza instrumentação (no
exemplo, através de um microscópio), enquanto outro computador dispõe de grande
capacidade para armazenamento de dados.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=gridarch.eps,width=123mm,height=110mm}
\insimg{1}{imagens/gridarch.png}
\caption{Arquitetura de um Grid Computacional}
\label{fig:gridarch}
\end{center}
\end{figure}

A Tabela~\ref{tab:platforms} resume as características das plataformas de
execução de aplicações paralelas discutidas aqui. Mantenha em mente, entretanto,
que a Tabela~\ref{tab:platforms} descreve características típicas dos diferentes
tipos de plataformas de execução. Certas plataformas podem apresentar
características arquiteturais adicionais que impactam na performance das
aplicações paralelas que nela executam. Por exemplo, alguns MPPs oferecem
suporte de hardware a memória compartilhada, através de uma tecnologia
denominada DSM (Distributed Shared Memory), o que melhora o desempenho de
aplicações baseadas em memória compartilhada. Uma vez que Grids são o nosso foco
neste texto, caso o leitor queira mais detalhes sobre plataformas de execução de
aplicações paralelas tradicionais (SMPs, MPPs e {\sc NoW}s) sugerimos a leitura
do trabalho de De Rose e Navaux~\cite{rose-fundamentos}.

Mesmo quando não há distinções arquiteturais, diferentes plataformas do mesmo
tipo podem diferir consideravelmente. Em particular, um Grid pode diferir
radicalmente de outro. Por exemplo, considere o TeraGrid~\cite{teragrid}, o
SETI@home~\cite{anderson-setiathome} e o {\sc Pauá}~\cite{cirne-paua}. 

O TeraGrid é um Grid que interliga 10 centros de supercomputação
norte\-a\-me\-ri\-ca\-nos através de canais de altíssima velocidade (40
GigaBits/segundo). Cada um dos centros possui milhares de processadores
dedicados ao TeraGrid, gerando um poder agregado de aproximadamente 20
TeraFlops. O SETI@home, por outro lado, utiliza a capacidade computacional
ociosa de computadores que se juntam voluntariamente ao sistema através da
instalação do software cliente do projeto. Em Março de 2005, SETI@home contava
com aproximadamente 5.3 milhões de processadores espalhados em 226 países. O
{\sc Pauá}, por sua vez, tem uma escala intermediária, pois congrega 10 domínios
administrativos espalhados pelo Brasil (ver {\em
  http://pauastatus.lsd.ufcg.edu.br}) e tem como infraestrutura o OurGrid, que
se baseia em uma rede peer-to-peer para o compartilhamento de recursos entre os
sites (i.e. Rede de Favores~\cite{andrade-ourgrid}). Apenas considerando essas
breves descrições é notável a diferença entre os três Grids. Outro aspecto
interessante de se verificar é que apesar do TeraGrid congregar um número
semelhante de sites, comparado ao {\sc Pauá}, o TeraGrid tem muito mais recursos
{\sc Pauá}. 

O conceito de acoplamento do Grid (i.e. quão próximos estão seus componentes) é
fundamental para compreendermos quais aplicações podem executar eficientemente
em um Grid. Note que acoplamento tem uma relação com conectividade. Voltando ao
exemplo acima, o SETI@home e o {\sc Pauá} têm seus focos em aplicações
fracamente acopladas, enquanto o TeraGrid pode propiciar condições para execução
eficiente de aplicações fortemente acopladas).

\begin{table}[htb]
\scriptsize
\centering
\begin{tabular}{|c||c|c|c|c|}\hline
                      & {\sc SMP} & {\sc MPP} & {\sc NoW} & Grid \\\hline
{\bf Conectividade}   & excelente & muito boa & boa       & regular/ruim \\\hline
{\bf Heterogeneidade} & nula      & baixa     & média     & alta  \\\hline
{\bf Compartilhado}   & não       & não       & sim       & sim  \\\hline
{\bf Imagem}          & única     & comum     & comum     & múltipla  \\\hline
{\bf Escala}          & 10        & 1.000     & 1.000     & 100.000 \\\hline
\end{tabular}
\normalsize
\caption{Comparação entre as plataformas de execução para aplicações paralelas}\label{tab:platforms}
\end{table}

\subsection{Execução Remota}
\label{sec:remota}

Na Seção~\ref{sec:plataforma} apresentamos o Grid como uma plataforma de execução de aplicações paralelas. Além disso, apresentamos o que diferencia os Grids de outras plataformas mais tradicionais para processamento de alto desempenho. Vale ressaltar que o componente fundamental dos Grids para Alto Desempenho é o {\em serviço de execução remota}. Este serviço é responsável por qualificar o grid como plataforma de execução de aplicações paralelas.

Um Grid que fornece serviços de execução remota possui várias vantagens. Uma delas é a possibilidade de converter este serviço genérico de execução de aplicações em qualquer outro serviço mais específico. Por exemplo, oferecer um serviço de processamento de imagens que utiliza várias instâncias do serviço de execução remota dispersos por todo Grid. 

Em contrapartida, a introdução dessa flexibilidade adquirida através do fornecimento de um serviço de execução genérico, que pode ser convertido em outros serviços mais específicos, aumenta a complexidade da infraestrutura. Portanto, novas questões devem ser consideradas para que seja possível fornecer um serviço de execução remota eficiente. Por exemplo, quais serviços de execução remota, disponíveis no Grid, devem ser usados, de forma a obter uma execução eficiente da aplicação de processamento de imagens? Como proteger o serviço de aplicações maliciosas? Discutiremos várias dessas questões nas próximas seções.

\subsection{Escalonamento}
\label{sec:sched}

Um dos aspectos mais importantes para o desenvolvimento dos Grids é a
implementação de estratégias de alocação de recursos para as várias aplicações
que usam a infraestrutura. Sendo assim, tanto é possível pensar em escalonamento
de aplicações, bem como escalonamento de recursos. Em geral, os objetivos dessas
duas visões contrastam entre si. A primeira procura melhorar o desempenho da
aplicação. A segunda busca aumentar a utilização dos recursos. Nesta seção
discutiremos essas duas visões sobre escalonamento, bem como heurísticas de
escalonamento de aplicação.

\subsubsection{Escalonamento de aplicação vs. Escalonamento de recurso}
\label{sec:schedAppvsRes}

Tradicionalmente, há um escalonador que controla os recursos do sistema (i.e.,
não há como usar os recursos sem a autorização do escalonador). Por exemplo, o
sistema operacional controla o computador no qual roda, decidindo quando e aonde
(no caso de multiprocessadores) cada processo executa. Chamaremos estes
escalonadores de {\em escalonadores de recursos}. Uma característica importante
dos escalonadores de recurso é que eles recebem solicitações de vários usuários
e, portanto, tem que arbitrar entre estes vários usuários o uso dos recursos que
controlam.

Devido à grande escala, ampla distribuição e existência de múltiplos domínios
administrativos, não é possível construir um escalonador de recursos global para
Grids. Uma razão para isto é que sistemas distribuídos que dependem de uma visão
global coerente (necessária ao controle dos recursos) apresentam problemas de
escalabilidade. Além disso, é muito difícil (senão impossível) convencer os
administradores dos recursos que compõem o Grid a abrir mão do controle de seus
recursos. 

Assim sendo, para utilizar recursos controlados por vários escalonadores de
recurso distintos, alguém tem que (i) escolher quais recursos serão utilizados
na execução da aplicação, (ii) estabelecer quais tarefas cada um destes recursos
realizará, e (iii) submeter solicitações aos escalonadores de recurso
apropriados para que estas tarefas sejam executadas. Esta é o papel do {\em
  escalonador de aplicação}. Escalonadores de aplicação não controlam os
recursos que usam. Eles obtêm acesso a tais recursos submetendo solicitações
para os escalonadores que controlam os recursos.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=SchedulingScenario.ps,width=108mm,height=89mm}
\insimg{1}{imagens/SchedulingScenario.png}
\caption{Ilustração de um cenário composto de vários escalonadores}
\label{fig:sched}
\end{center}
\end{figure}

Ou seja, em um Grid, as decisões de escalonamento são divididas em duas camadas,
com parte da responsabilidade pelo escalonamento sendo transferida dos
escalonadores de recurso para o nível de aplicação. A Figura~\ref{fig:sched}
ilustra um cenário de escalonamento em um Grid Computacional.

As decisões tomadas pelo escalonador de aplicações (quais recursos serão
utilizados e quais tarefas cada um destes recursos realizará) são normalmente
baseadas em um modelo do desempenho da aplicação e em dados sobre o estado atual
dos vários recursos que formam o
Grid~\cite{apples-berman,casanova-sufferage,shao-predict,jon-grimshaw,jon-gallop,zhu-adaptive}.
Portanto, escalonadores de aplicação têm que conhecer detalhes das aplicações
que escalonam, i.e. eles são construídos com uma aplicação (ou classe de
aplicações) em mente. Além disso, escalonadores de aplicação normalmente
precisam saber quanto tempo cada recurso vai levar para processar uma dada
tarefa. Sem esta informação, é difícil escolher os melhores recursos a utilizar,
como também determinar qual tarefa alocar a cada um desses recursos. Para obter
tal informação, foram desenvolvidos sistemas que monitoram e prevêem o
comportamento futuro de diversos tipos de
recursos~\cite{lowekamp-resource,wolski-nws}. Este esquema de obtenção de
informação baseado em monitoração tem se mostrado eficaz quando os recursos
monitorados são redes TCP/IP ou computadores compartilhados no tempo, mas ainda
há questões quanto a escalabilidade dos sistemas de
monitoração~\cite{francis-distance}.

\subsubsection{Previsão de Desempenho}

Apesar de serem úteis e ajudarem no desenvolvimento de heurísticas de
escalonamento eficientes, as infraestruturas de monitoração e previsão de
desempenho têm um desafio imposto pela escala que um Grid computacional pode
alcançar. Além disso, devido a descentralização do controle sobre os recursos no
Grid, é possível que por questões de segurança alguns domínios administrativos
não adotem a implantação de sistemas de monitoração, a fim de fornecer
informações de previsão de desempenho para escalonadores de aplicação.

Mesmo assim, é pensando na possibilidade de prover um melhor desempenho no
escalonamento de aplicações que alguns sistemas de previsão de desempenho foram
desenvolvidos. Como consequência várias heurísticas foram desenvolvidas
dependendo das informações fornecidas por estas infraestruturas de
monitoração~\cite{casanova-sufferage,apples-berman}.

Uma serviço utilizado por várias heurísticas de escalonamento é o {\em Network
  Weather Service} ({\sc nws})~\cite{wolski-nws}. O {\sc nws} é um sistema que
  monitora e dinamicamente provê estimativas de desempenho de recursos
  computacionais (ex.: processadores e rede). O processo de monitoração é feito
  através de sensores que mede periodicamente o estado dos recursos. As
  informações coletadas pelos sensores podem ser requisitadas diretamente pelas
  heurísticas, que utilizam essa informação para melhorar a eficiência do
  escalonamento gerado. 

Além da informação sobre o desempenho de um recurso, em um dado instante, fornecido pelos sensores, as heurísticas podem
fazer uso de previsões de desempenho que são geradas pelo {\sc nws} a partir do histórico obtido com a
monitoração. Assim, através do uso de métodos numéricos (e.g. regressão linear) as informações armazenadas sobre o
desempenho dos recursos são processadas para gerar estimativas do desempenho que os recursos podem oferecer em um
determinado intervalo.

Considerando o benefício que uma arquitetura de monitoração, que forneça
in\-for\-ma\-ções sobre os recursos do Grid, o Global Grid Fórum~\cite{ggf-site}
mantém grupos de trabalho discutindo sobe questões relacionadas à definição de
uma arquitetura de monitoração. Estas discussões são, em geral, baseadas na
experiência obtida de investimentos já feitos por vários grupos, como {\sc
  nws}~\cite{wolski-nws} e {\em Autopilot}~\cite{ribler-autopilot}, dentre
outros trabalhos~\cite{waheed-infra,smith-control,tierney-monitor}. A
arquitetura proposta é baseada na idéia de {\em produtor/consumidor} de eventos
disparados pelos sensores que monitoram os
recursos~\cite{tierney-ggfdoc}. Apesar da evolução conceitual que a padronização
pode introduzir na área de previsão de performance para sistemas distribuídos,
muito ainda tem que ser feito para se ter uma infraestrutura amplamente
disponível. 

A seguir descreveremos algumas situações onde um serviço de previsão de
desempenho é extremamente útil, bem como estratégias eficientes de escalonamento
de aplicação que não dependem de informação sobre os recursos do Grid nem da
aplicação.

\subsubsection{Aplicações Fortemente Acopladas}
\label{sec:jacobi}

Jacobi AppLeS~\cite{apples-berman} é um exemplo interessante, primeiro por ter introduzido a idéia de escalonamento de
aplicações e também por fornecer uma solução de escalonamento para uma aplicação bem conhecida (i.e. Jacobi). 

{\em Jacobi} é um método usado para resolver a aproximação por diferenças finitas da equação de Poisson e portanto é aplicável
a problemas que envolvem fluxo de calor, eletrostática e gravitação. Além de ser interessante por si só, Jacobi pode ser
visto como uma instância de uma importante classe de aplicações paralelas: aplicações fortemente acopladas de
paralelismo em dados.

Jacobi AppLeS é um escalonador para Jacobi 2D. Em Jacobi 2D, o domínio do problema é discretizado em uma matriz
bidimensional. Em cada iteração, cada elemento da matriz é atualizado com a média dos seus quatro vizinhos. Jacobi
termina por convergência, isto é, quando uma iteração altera muito pouco os elementos da matriz. 

Quando Jacobi é executado em um {\sc mpp} ({\em Massive Parallel Processor}), a
matriz bidimensional é tipicamente dividida em ambas as dimensões, gerando
submatrizes de igual tamanho. Cada submatriz é então alocada a um processador. A
cada iteração, portanto, é necessário comunicação entre processadores para troca
das fronteiras das submatrizes. A Figura~\ref{fig:jacobi} mostra a distribuição
de dados entre 4 processadores de um {\sc mpp} alocados para executar
Jacobi. Como, em um {\sc mpp}, os processadores são idênticos e dedicados, esta
simples estratégia de alocação de trabalho balanceia a carga entre os
processadores, garantindo bom desempenho. 

Em um Grid, entretanto, processadores e canais de comunicação são
heterogêneos. Além disso, outras aplicações estão concorrendo pelos mesmos
recursos (processadores e canais de co\-mu\-ni\-ca\-ção) enquanto Jacobi
executa. Conseqüentemente, a estratégia descrita acima provavelmente vai
produzir um desbalanço de carga, afetando o desempenho. Mais ainda, uma vez que
as condições de carga do Grid variam dinamicamente, o que é uma boa divisão de
carga vai variar a cada execução da aplicação. Finalmente, devido à existência
de canais de comunicação mais lentos e compartilhados com outras aplicações,
talvez não valha a pena utilizar todos os processadores disponíveis.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=Jacobi.ps,width=49mm,height=49mm}
\insimg{1}{imagens/Jacobi.png}
\caption{Jacobi executando em quatro processadores em um MPP}
\label{fig:jacobi}
\end{center}
\end{figure}

A solução oferecida por AppLes Jacobi se baseia em três elementos principais. Primeiro, o escalonamento em si é
simplificado pela decisão de utilizar um particionamento unidimensional. Segundo, o escalonador se utiliza do {\sc
  nws}~\cite{wolski-nws} para obter previsões de curto prazo da disponibilidade de cada processador e da latência e
banda da comunicação entre quaisquer dois processadores. Terceiro, o escalonador dispõe de um modelo de performance da
aplicação, que é usado para avaliar suas decisões. Este modelo é o seguinte:

\begin{equation}
T_i = A_i \times P_i + C_i
\end{equation}

\begin{itemize}

   \item $T_i$ é o tempo para o processador $i$ executar uma iteração.

   \item $A_i$ é a área da submatriz alocada ao processador $i$.

   \item $P_i$ é o tempo que o processador $i$ leva para computar um elemento.

   \item $C_i$ é o tempo que o processador $i$ leva para comunicar suas fronteiras.

\end{itemize}

Note que $P_i$ e $C_i$ são estimados com base nos dados fornecidos pelo {\sc nws}.

O escalonamento propriamente dito começa ordenando os processadores por uma distância específica da aplicação (que
cresce quadraticamente com a diferença de velocidade dos processadores e linearmente com a diferença de suas
capacidades de co\-mu\-ni\-ca\-ção). Uma vez os processadores ordenados, tenta-se iterativamente uma solução com os $n$
primeiros processadores, até que a solução com $n - 1$ processadores se mostre mais rápida, ou até que não haja mais
processadores. Naturalmente, o tempo de uma iteração é estimado como o maior $T_i$ de todos os processadores. Fixados $n$
processadores, a solução de escalonamento é obtida dividindo a matriz proporcionalmente a $P_i$.

Por exemplo, suponha que o Grid tem quatro processadores: $P_0$, $P_1$, $P_2$ e $P_3$. Assuma ainda que $P_0$ e $P_1$
tem o dobro da velocidade de $P_2$ e $P_3$, que $P_1$ tem uma outra aplicação rodando e só poderá dedicar 50\% de seu
poder computacional a aplicação, que $P_3$ está conectado a uma rede que vivencia intenso tráfego e que sua comunicação
está ordens de grandeza mais lenta que entre os demais processadores. Uma vez que $P3$ está se comunicando muito
lentamente, o AppLeS não vai utilizá-lo para esta execução. Note que esta decisão não descarta a possibilidade que $P_3$
venha a ser usado em uma futura execução da aplicação, quando as condições da rede forem diferentes. Note também que,
embora $P_1$ seja duas vezes mais rápido que $P_2$, uma vez que só 50\% de $P_1$ está disponível, $P_1$ e $P_2$ são
idênticos para a aplicação (pelo menos nesta execução). A Figura~\ref{fig:jacobi2} mostra o resultado que o AppLeS
Jacobi produziria neste cenário.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=Jacobi2.ps,width=49mm,height=49mm}
\insimg{1}{imagens/Jacobi2.png}
\caption{Escalonamento feito pelo Jacobi AppLes}
\label{fig:jacobi2}
\end{center}
\end{figure}

Devemos salientar que um aspecto importante para o bom funcionamento do Jacobi AppLeS é o tempo relativamente curto de
execução da aplicação. O tempo de execução dos experimentos descritos em~\cite{apples-berman} é da ordem de segundos,
casando perfeitamente com as previsões de curto prazo do {\sc nws}. Para aplicações que executam por mais tempo (horas,
digamos), seria necessário prever a disponibilidade de recursos do Grid por prazos mais longos. Uma alternativa
interessante seria construir um escalonador que, além do escalonamento inicial, continuasse funcionando para reescalonar
a aplicação caso as condições do Grid mudassem consideravelmente~\cite{shao-predict}. Neste caso, naturalmente, a
aplicação teria que ser escrita para permitir tal reescalonamento, suportando a redistribuição de trabalho durante a
execução.

Note que as previsões de performance fornecidas pelo {\sc nws} são fundamentais
para o funcionamento do Jacobi AppLeS. De fato, a vasta maioria dos
escalonadores de aplicação descritos na
literatura~\cite{apples-berman,casanova-sufferage,shao-predict,jon-grimshaw,jon-gallop,zhu-adaptive}
utiliza alguma forma de previsão de performance. Infelizmente, há problemas em
aplicar em larga escala os sistemas de monitoração e previsão existentes (como
{\sc nws}~\cite{wolski-nws} e Remos~\cite{waldspurger-stride}), especialmente
quando se trata de prever o comportamento dos canais de comunicação, que crescem
quadraticamente com o número de máquinas do Grid. Em Francis, et
al.~\cite{francis-distance} é apresentada uma discussão sobre a dificuldade e se
construir um sistema escalável para monitoramento de canais de comunicação.

\subsubsection{Aplicações {\em Bag-of-Tasks}}
\label{sec:wqr}

Apesar de ser possível efetuar escalonamentos eficientes usando informação sobre
o desempenho dos recursos, muitas aplicações podem ser escalonadas de forma
eficiente sem o uso dessa informação. Isso é possível devido a algumas
características da aplicação. Em particular, aplicações Bag-of-Tasks são
aplicações que podem ser escalonadas sem o uso de informação dinâmica sobre o
Grid (e.g. carga de CPU, largura de banda).

Como parte do projeto OurGrid~\cite{ourgrid-site}, foram desenvolvidas duas
heurísticas de escalonamento, o Work Queue with Replication ({\sc
  wqr})~\cite{paranhos-trading}, um escalonador capaz de obter boa performance
para a aplicação no ambiente muito dinâmico que é o Grid sem depender de
previsões de performance dos componentes do Grid. Isto é possível devido a dois
fatores fundamentais. Primeiro, {\sc wqr }usa replicação de tarefas para
garantir a boa performance da aplicação. A idéia é utilizar alguns ciclos extra
para compensar pela falta de informação sobre o ambiente. Segundo, {\sc wqr}
escalona aplicações relativamente simples.  

A idéia aplicada na heurística {\sc wqr} é bastante simples e ao mesmo tempo
poderosa. Uma fila de tarefas é criada na submissão da aplicação. Sempre que há
um processador disponível, uma tarefa é enviada para este processador. Quando
não há mais tarefas para enviar (i.e. a fila de tarefas está vazia), uma das
tarefas em execução é replicada. Quando uma das replicas termina, as demais
réplicas são abortadas pelo escalonador. Para evitar o desperdício de poder
computacional, é estabelecido o máximo de replicas que uma tarefa pode
ter. Nossos experimentos mostraram um resultado bastante animador, eles indicam
que grande parte do ganho de desempenho obtido pelo {\sc wqr} se manifesta com
um grau de replicação $2$.

Considere a Figura~\ref{fig:wqr}, que mostra o desempenho do {\sc wqr} em comparação com o {\em Workqueue}, o
Sufferage~\cite{ibarra-heuristic} (um bom escalonador baseado em informações sobre o Grid e sobre as tarefas), e com o
Dynamic FPLTF (Dynamic Fastest Processor to Largest Task First, outro bom escalonador que utiliza informações sobre o
Grid e sobre as tarefas). Este resultado apresenta o tempo médio obtido pelos quatro algoritmos de escalonamento em função da
heterogeneidade das tarefas (quanto maior, mais heterogêneo). Note que {\sc wqr} foi executado três vezes, com
replicação máxima de 2, 3 e 4 processadores. Observe também que Sufferage e Dynamic FPLTF tiveram informação perfeita
sobre o desempenho dos recursos do Grid, bem como das tarefas que formam a aplicação, algo inatingível na
prática. Portanto, é um excelente resultado o fato de {\sc wqr} obter desempenho comparável com Sufferage e Dynamic
FPLTF baseados em informação perfeita.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=wqr_performance.eps,width=92mm,height=70mm}
\insimg{1}{imagens/wqr_performance.png}
\caption{Desempenho do {\sc wqr}}
\label{fig:wqr}
\end{center}
\end{figure}

Obviamente, {\sc wqr} consome mais ciclos que os algoritmos de escalonamento
tradicionais. A Figura 10 mostra o consumo adicional de CPU em função da
heterogeneidade das tarefas. Em situações que a heterogeneidade de tarefas é
pequena, este consumo não é significativo, não ultrapassando $15\%$. Por outro
lado, quando tarefas são muito heterogêneas, {\sc wqr} desperdiça uma quantidade
considerável de ciclos. De fato, o desperdício pode chegar próximo a
$100\%$. Entretanto, tal problema pode ser controlado pela limitação do número
máximo de replicas de uma tarefa. Quando limitamos {\sc wqr} a usar 2 replicas
({\sc wqr} 2x), temos que o desperdício de CPU fica sempre abaixo de $40\%$.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=wqr_performance.eps,width=104mm,height=80mm}
\insimg{1}{imagens/wqr_waste.png}
\caption{Desperdício de ciclos com a replicação}
\label{fig:deswqr}
\end{center}
\end{figure}

\subsubsection{Aplicações que Processam Grandes Quantidades de Dados}
\label{sec:affinity}

Apesar de {\sc wqr} ser uma heurística eficiente, ela apresenta uma limitação, o bom desempenho é alcançado apenas para
aplicações {\em cpu-intensive}. Ou seja, caso a aplicação necessite processar grandes quantidades de dados, o que
implicará em muitas transferências, a replicação pode não ter o mesmo efeito.

Uma grande parte das aplicações Bag-of-Tasks necessitam processar grandes
quantidades de dados. Por exemplo, bioinformática~\cite{gish-blast},
Seti@Home~\cite{anderson-setiathome}, renderização de
imagens~\cite{davis-parallel,lee-parallel,santos-neto-viz,high-energy-physics}.
Sendo assim, uma heurística de escalonamento que melhore o desempenho dessas
aplicações é bastante relevante. 

\begin{figure}[ht]
\centering
%\epsfig{file=MakespanbyExecution.all.ps,width=78mm,height=108mm,angle=270}
\insimg{1}{imagens/MakespanbyExecution_all.png}
\caption{Sumário do desempenho de \textit{Storage Affinity} comparado com outras heurísticas}
\label{fig:makespan-all}
\end{figure}

Felizmente, algumas aplicações apresentam características que podem ser
exploradas por heurísticas de escalonamento para obter escalonamentos
eficientes. Pensando nisso, foi desenvolvida a heurística~\textit{Storage
Affinity}\cite{santos-neto-exploiting}, que explora padrões de reutilização de
dados e aplica replicação de forma semelhante a {\sc wqr}.

Os padrões de reutilização foram classificados em dois tipos básicos, {\em
  inter-job} e {\em inter-task}. O padrão {\em inter-job} determina que há
reutilização de dados entre execuções sucessivas das aplicações. Vale salientar
que isso é bastante comum em aplicações do tipo {\em Parameter
  Sweep}~\cite{casanova-apst}. Outra situação de reutilização é capturada pela
definição do padrão {\em inter-task}, aplicações que apresentam esse padrão
possuem reutilização de dados durante um execução. Por exemplo, aplicações de
busca de seqüências de {\sc dna}, como o Blast~\cite{gish-blast}, podem
apresentar esse padrão, considerando que várias seqüências podem ser pesquisadas
em paralelo usando o mesmo banco de dados de seqüências catalogadas. 

Portanto, a idéia é explorar ambos os padrões de reutilização de dados para
melhorar o desempenho das aplicações. Assim, Storage Affinity efetua o
escalonamento baseado {\em afinidade} que as tarefas têm com os sites que formam
o Grid. O valor da {\em afinidade} determina {\em quão próximo} do site esta
tarefa está. A semântica do termo {\em próximo} está associada à quantidade de
bytes da entrada da tarefa que já está armazenada remotamente em um dado site,
ou seja, quanto mais bytes da entrada da tarefa já estiver armazenado no site,
mais próximo a tarefa estará do site, pois poderá iniciar sua execução mais
rapidamente. Assim, o valor da {\em afinidade} de uma tarefa com um site {\em é
  o número de bytes pertencentes à entrada da tarefa, que já estão armazenados
  no site\/}. 

Note que {\em Storage Affinity} utiliza tão somente as informações sobre o
tamanho e a localização dos arquivos de entrada. É importante dizer que tais
informações podem estar disponíveis no instante do escalonamento sem dificuldade
e perda de precisão. Por exemplo, as informações relacionadas aos dados de
entrada de uma tarefa podem ser obtidas através de requisições aos recursos de
armazenamento de dados. Mesmo que estes recursos não sejam capazes de responder às
requisições sobre {\em quais elementos\/} de dados eles armazenam e {\em qual o
  tamanho\/} de cada elemento de dado, uma implementação alternativa da
heurística {\em Storage Affinity} poderia facilmente manter um histórico das
informações sobre as transferências efetuadas para cada tarefa e assim possuir
tais informações.

\begin{figure}[ht]
\centering
%\epsfig{file=WastingbyExecution.ps,width=78mm,height=108mm,angle=270}
\insimg{1}{imagens/WastingbyExecution_all.png}
\caption{Sumário do desperdício de recursos por \textit{Storage Affinity} comparado com outras heurísticas}
\label{fig:waste-all}
\end{figure}

Além de aproveitar a reutilização dos dados, {\em Storage Affinity\/} também
trata a dificuldade na obtenção de informações dinâmicas sobre o Grid, bem como
informações sobre o tempo de execução das tarefas da aplicação. Para resolver
este problema, {\em Storage Affinity} efetua {\em replicação de tarefas}. 

{\em Storage Affinity\/} executa em duas fases. Na primeira fase, cada tarefa é
associada a um processador. A ordem de escalonamento é determinada através do
cálculo do valor da {\em afinidade} das tarefas. Após determinar as afinidades,
a tarefa que apresentar o maior valor é escalonada em um processador do site com
o qual a tarefa apresentou maior afinidade. A segunda fase consiste da
replicação de tarefas. Esta fase inicia quando não há mais tarefas aguardando
para executar e pelo menos um processador está disponível. Uma réplica {\em
  pode} ser criada para qualquer tarefa em execução. Contudo, ao contrário de
{\sc wqr}, há um critério e uma ordem de prioridade para criação de
réplicas. Considerando que o grau de replicação de uma tarefa é o número de
réplicas criadas para esta tarefa, então ao iniciar a fase de replicação, os
seguintes critérios são verificados na escolha de qual tarefa deve ser
replicada: $i)$ a tarefa deve estar executando e ter um valor de afinidade
positivo, ou seja, alguma porção de sua entrada já deve estar presente no site
de algum dos processadores disponíveis no momento; $ii)$ o grau de replicação
corrente da tarefa deve ser o menor entre as tarefas que atendem o critério
$(i)$; e $iii)$ a tarefa deve apresentar o maior valor de afinidade entre as
tarefas que atendem o critério $(ii)$. 


Quando uma tarefa completa sua execução as outras réplicas da tarefa são
interrompidas. O algoritmo finaliza quando todas as tarefas que estão executando
completam. Até isto ocorrer, a replicação de tarefas continua. 

Na Figura~\ref{fig:makespan-all} é apresentado uma comparação de desempenho
entre três heurísticas: {\sc wqr}, {\em XSufferage} e {\em Storage
  Affinity}. Esses resultados foram obtido através da investigação de mais de
3.000 cenários, onde vários aspectos foram considerados (i.e. heterogeneidade do
Grid e da aplicação, tipo da aplicação e granularidade da
aplicação)~\cite{santos-neto-exploiting}. É possível ver que Storage Affinity
consegue melhor desempenho que heurísticas que usam informação sobre o ambiente
(XSufferage).

Um detalhe importante, mostrado na Figura~\ref{fig:waste-all} é a grande
diferença de desperdício de recurso entre Storage Affinity e {\sc wqr}. Esse
efeito é produzido devido ao uso de estratégias de replicação diferentes pelas
heurísticas. O fato de {\sc wqr} não evitar transferências reduz o desperdício
de CPU, por outro lado eleva bastante o desperdício de largura de banda da
rede. Para Storage Affinity ocorre exatamente o contrário.

\subsection{Imagem do Sistema}

Ao usamos um computador, dependemos das abstrações criadas pelo sistema
operacional, tais como arquivos, diretórios, permissões e processos, para
lidarmos com o sistema. São tais abstrações que nos permitem expressar o
queremos fazer. Elas também nos permitem nomear os dados persistentes que temos
armazenados no sistema. Através destas abstrações básicas fornecidas pelo
sistema operacional, o usuário tem uma imagem do sistema, formada pelo conjunto
de objetos que ele pode manipular e pelas regras de manipulação destes objetos.

Plataformas de execução de aplicações paralelas que tem uma única instância do
sistema operacional (SMPs) automaticamente fornecem a seus usuários uma imagem
única do sistema. Já em plataformas que contém várias instâncias do sistema
operacional (MPPs, NOWs e Grids), é necessário construir uma imagem consistente
do sistema. Uma imagem consistente do sistema cria a ilusão (ainda que
imperfeita) que os objetos que o usuário pode manipular são acessíveis da mesma
forma de qualquer processador que compõe a plataforma.

MPPs e NOWs contam com boa conectividade e administração centralizada. Isso
permite a configuração dos processadores que compõem a plataforma para
compartilhar o mesmo cadastro de usuários e os sistemas de arquivo mais
importante (o /home, por exemplo), criando assim uma imagem razoavelmente
consistente do sistema. Grids, por outro lado, são amplamente dispersos e muitas
vezes sob controle de diversas entidades administrativas distintas. Não é
factível, por exemplo, simplesmente montar o mesmo /home em todos os
processadores que compõem o Grid, pois, além de problemas de desempenho, há
também questões administrativas. Por outro lado, não queremos deixar que o
usuário tenha que lidar com várias imagens totalmente distintas do sistema.

As soluções para este problema dividem-se em dois grandes grupos, aquelas que
evitam os problemas administrativos trabalhando à nível de
usuário~\cite{condor-hunter,vadaht-webos} e aquelas que introduzem novas
abstrações para que o usuário possa lidar com o
Grid~\cite{cirne-mygrid,cirne-open}. Em princípio, soluções à nível de usuário
são mais simples de usar pois suportam abstrações já conhecidas pelo usuário
(e.g. arquivos). Entretanto, elas podem apresentar sérios problemas de
performance dependendo da aplicação e da conectividade do Grid. Novas
abstrações, ao contrário, requerem o aprendizado de novos conceitos, mas podem
vir a oferecer uma forma mais eficiente de usar o Grid.

\subsection{Segurança}

Um dos desafios impostos pela introdução de um serviço de execução remota (ver
Seção \ref{sec:remota}) em um Grid é relacionado a segurança. Ou seja, os
problemas de segurança podem afetar não apenas o proprietário do recurso, como
também o usuário da aplicação. Ou seja, o recurso estará exposto ao permitir a
execução de uma aplicação de um usuário de origem, a princípio,
desconhecida. Por outro lado, o usuário não gostaria que sua aplicação fosse
{\em sabotada} durante a execução gerando resultados não confiáveis.

Portanto, segurança é um tópico que deve se considerado para o desenvolvimento
dos Grids Computacionais. Nesta seção iremos abordar algumas questões de
segurança que surgem ao se pensar em uma infraestrutura de computação na escala
de um Grid Computacional. 

\subsubsection{Proteção dos recursos}
\label{sec:protectresource}

Uma vez que o Grid é formado por vários domínios administrativos distintos,
naturalmente é possível que a execução de uma aplicação seja iniciada de uma
domínio $X$ e utilize recursos dos domínios $Y$ e $Z$. Porém, como saber se a
aplicação iniciada por um usuário do domínio $X$ não contêm código malicioso que
podem prejudicar o funcionamento dos recursos utilizados? 

Uma primeira, e óbvia, medida é implementar mecanismos de autenticação e
autorização para permitir que apenas usuários do domínio $X$, que sejam
autenticados pelos outros domínios, possam acessar os recursos autorizados por
estes domínios. Ainda assim, não se pode garantir que a {\em credencial de
  acesso} do usuário não está sendo usada de forma incorreta, seja por corrupção
(e.g. uso da máquina para disparar ataques de interrupção de serviço) ou
acidentalmente (e.g. uma falha na aplicação pode criar uma
vulnerabilidade)~\cite{vulnerabilities-setiathome}. 

É justamente por não ter garantias a esse respeito que mecanismos de proteção
para os recursos têm sido desenvolvidos. A idéia básica é criar um ambiente
isolado, que no caso de ser comprometido não prejudique o funcionamento do
recurso. Uma abordagem comum é a utilização de
virtualização~\cite{kamp-jail,sarmiento-jail,xen-art}.

Uma das abordagens é implementada pelo Jail~\cite{kamp-jail,sarmiento-jail}, que
surgiu para prover maior flexibilidade no gerenciamento de sistemas FreeBSD. A
idéia é que o esquema de autorização clássico do Unix é pouco sofisticado para
situações onde há uma demanda por uma granularidade mais fina nos níveis de
permissões sobre o recursos. Essa estratégia funciona através do confinamento de
um processo e seus descendentes em uma área (i.e. {\em jail}), nesta área o
processo só pode acessar outros processos, sistemas de arquivo e recursos de
rede que se encontram na mesma {\em partição}.

Uma partição é criada através da invocação à chamada de sistema $jail()$. Além
disso, o escopo do sistema de arquivos visível pelo processo confinado é
utilizando a chamada de sistema $chroot()$. Esta chamada foi modificada para
corrigir vulnerabilidades que não permitiam a redução da visibilidade do
processo com relação aos sistema de arquivos~\cite{kamp-jail}.  

Note que não estamos tratando de partição necessariamente no que se refere ao
sistema de arquivos. A partição (ou jail) na qual o processo deverá estar
confinado é composta de um ambiente com sistema de arquivos, processos e rede
isolados de outros processos. 

Uma das vantagens do Jail é que um usuário pode interagir com o recurso,
enquanto algum processo remoto executa em uma partição isolada do resto do
sistema. Porém, isso pode causar inconvenientes para o usuário interativo, que
na maioria dos casos não está disposto a contribuir com seu recurso para o Grid,
caso isso implique em um consumo exagerado do recurso por parte do processo
estrangeiro. Sendo assim, outras alternativas fornecem mecanismos de {\em
  detecção de ociosidade} que prepara o ambiente para receber processos
estrangeiros e executá-los em uma partição independente. Assim, espera-se que o
usuário local não seja prejudicado por um processo que, por exemplo, consume
muita memória, uma vez que o recurso estaria ocioso.

Outras soluções têm o objetivo de não apenas garantir que o sistema estará a
salvo de qualquer tentativa de danificação, como de início de ataques a partir
do recurso, como protegerá o usuário de inconvenientes causados por aplicações
que utilizam muito da capacidade do recurso. Pensando nisso, o Swan é uma
solução de {\em sandboxing} baseado na máquina virtual Xen~\cite{xen-art}. O
Swan é dividido em dois módulos: $i)$ {\em Mode Switcher}; $ii)$ {\em Virtual
  Machine}.

O primeiro módulo é responsável por monitorar o recurso, no intuito de detectar
sua ociosidade. Ao detectar a ociosidade o recurso muda do sistema operacional
no qual o usuário normalmente trabalha, para um sistema operacional modificado
que garante o isolamento da aplicação remota do resto do sistema local. Isso
inclui um sistema de arquivos completamente diferente (i.e. uma partição do
disco diferente), a impossibilidade de enviar sinais para processos fora da
máquina virtual e a restrição no acesso aos recursos de rede da máquina na qual
está executando. A vantagem dessa abordagem é a exploração de ociosidade, porém
há o overhead gerado pela reinicialização em outro sistema operacional. 

No estado atual, não encontramos um padrão definido pelos comitês da área de
Grid Computing, porém vários projetos apresentam soluções semelhantes para a
proteção de recursos que formam o Grid.

\subsubsection{Proteção da aplicação}
\label{sec:protectapp}

Um outro lado da questão da segurança é a proteção da aplicação que executa no
Grid. Ou seja, garantir que não haverá sabotagem na execução do serviço
requisitado por um cliente. Por exemplo, suponha um serviço que fornece
renderização de imagens. O serviço supostamente estaria disponível para
responder a requisições de renderização de clientes espalhados por vários
domínios administrativos. Porém, por algum motivo, esse serviço prioriza as
requisições dos clientes locais e retorna sempre a mesma imagem para qualquer
requisição de clientes externos. Com isso o provedor do serviço pretende
economizar recursos que seriam destinados à computações estrangeiras.

Certamente, essa é uma situação simples de contornar, porém ainda assim pode
causar prejuízos para o usuário da aplicação cliente que requisitou a
renderização da imagem. Portanto, é necessário munir o cliente de mecanismos e
estratégias de proteção contra este tipo de sabotagem. 

Várias estratégias de tolerância à sabotagem já foram propostas para ambientes
de computação voluntária, onde essa prática parece ter um maior impacto, já que
os voluntários, em geral, não são
confiáveis~\cite{sarmenta-sabotagetolerance}. Um caso clássico foi o do
Seti@home, onde o que motivava a sabotagem era apenas o aspecto {\em
  fama}~\cite{anderson-setiathome}. Voluntários que mais fornecessem o serviço
de execução para estas infraestruturas figuravam em um ranking. Assim, através
de uma modificação no serviço de execução, se tornava possível {\em enganar} o
sistema retornando um resultado inválido que era contabilizado como trabalho
útil e melhorava a posição daquele voluntário no ranking.

Assim, uma estratégia simples é usar o que se chama de {\em majority
  voting}~\cite{sarmenta-sabotagetolerance}, que replica a execução de uma
unidade de trabalho entre vários voluntários do sistema e espera até que um
número $m$ de resultados finais coincidentes sejam retornados. Porém, esse
esquema tem suas limitações. Por exemplo, suponha um ambiente com um número
grande de voluntários que retornam resultados inválidos. A replicação crescerá
bastante em função deste número para tolerar essa quantidade de falhas. Isso,
portanto, acarretará um nível alto de desperdício de recursos.

Apesar da estratégia {\em majority voting} ter a vantagem de ser bastante
  simples de implementar, ela não tolera situações onde o número de resultados
  inválidos é muito alto. Desta forma, outras abordagens são propostas. Uma
  forma de contornar a limitação do {\em majority voting} é usar a política
  denominada {\em spot-checking}~\cite{sarmenta-sabotagetolerance}. Nesse
  esquema, os voluntários são verificados de forma aleatória através da
  solicitação de execução de um {\em benchmark}. A intenção é verificar se é
  possível confiar nos resultados gerados por este voluntário. Caso o {\em
  benchmark} detecte alguma falha na computação efetuada, ou seja, os resultados
  retornados pelo voluntário não conferem com o resultado esperado do teste, os
  resultados anteriores retornados por este voluntário são descartados e
  colocados na lista de trabalho pendente.

Uma vez que {\em spot-checking} é baseada na verificação aleatória da
confiabilidade dos voluntários. Assim, ao detectar que um voluntário não é
confiável, todos os resultados anteriores deste voluntário são
descartados e o trabalho é reenviado a outros voluntários. Nesse estratégia, há
uma menor repetição de trabalho, quando comparamos à estratégia {\em majority
  voting}. Existem duas variações da estratégia {\em spot-checking}: $i)$ {\em
  spot-checking with blacklist}; $ii)$ {\em spot-checking without
  blacklist}. A diferença entre as duas é o uso de uma lista com os voluntários
maliciosos. Essa lista indica os voluntários que não devem ser mais
considerados. Para uma maior discussão sobre as diferenças e implicações de cada
abordagem sugerimos ao leitor o trabalho de Sarmenta et al.~\cite{sarmenta-sabotagetolerance}.

Devido ao fato de nem sempre ser possível manter uma lista de voluntários
maliciosos de forma eficiente. Por exemplo, usar o IP para identificar
unicamente os voluntários maliciosos pode não ser uma boa idéia, pois é bastante
comum o fato dos hosts obterem IP dinâmicos todas as vezes que se
conectam. Sendo assim, para resolver essa limitação surge uma nova abordagem
baseada na definição de {\em credibilidade}~\cite{sarmenta-sabotagetolerance}. A
idéia é marcar vários objetos do sistema com um valor que descreve sua
credibilidade. Então, é possível que voluntários, resultados e grupos de
resultados tenham valores de credibilidade dependendo de vários fatores. Por
exemplo, novos voluntários que entram no sistema têm menos credibilidade que
antigos voluntários, onde seus resultados passaram com sucesso por vários {\em
  spot-checking}. Naturalmente, a credibilidade dos resultados do voluntário
terá bastante relação com sua própria credibilidade, que pode evoluir ao passo
que sua computação vai sendo verificada. Note que uma combinação de {\em
  majority voting} e {\em spot-checking} é uma alternativa possível para
determinação da credibilidade dos voluntários.
\clearpage
\section{Estudos de Caso}
\label{sec:estudo}
%\cutname{gridsestudosdecaso.html}

\subsection{Globus}
\label{sec:globus}

Globus consiste de um conjunto de serviços que facilitam a construção de
infraestruturas para Computação em Grid~\cite{globus-toolkit}. Os serviços
Globus podem ser usados para submissão e controle de aplicações, descoberta de
recursos, movimentação de dados e segurança no Grid. 

Apesar desses serviços fornecerem uma parte importante para a construção de
Grids Computacionais, existem outros serviços além desse núcleo. Estes serviços, igualmente importantes, podem ser construídos sobre essas camadas definidas como a base de serviços para a infraestrutura. Discutiremos nas seções seguintes os aspectos mais importantes dessa infraestrutura de serviços.

\subsubsection{Autenticação}

Um aspecto que complica o uso de Grids na prática é a autenticação de usuários
em diferentes domínios administrativos. Em princípio, o usuário tem que ser
autenticado para cada domínio administrativo de uma forma determinada pelo
administrador do domínio (que tipicamente envolve fornecer uma identificação de
usuário e uma senha). Este esquema coloca uma grande carga no usuário (quem usa
vários sites Web que exigem login, tem uma idéia bem concreta destes problemas).

No contexto de Computação em Grid, os problemas causados pela múltipla
au\-ten\-ti\-ca\-ção são agravados, pois queremos serviços que possam efetuar
ações automaticamente, porém essas ações exigem autenticação (e.g. submeter uma
tarefa para execução em um site remoto, solicitar o armazenamento ou acesso a um
determinado arquivo). Além disso, como o objetivo do Globus é permitir a criação
de organizações virtuais, através da agregação de recursos e serviços
distribuídos por vários domínios administrativos diferentes, certamente questões
relacionadas a delegação de credencial estão envolvidas no processo de
autenticação.

{\sc gsi} (Globus Security Infrastructure) é o serviço Globus que ataca estes
problemas. {\sc gsi} viabiliza o login único no Grid. {\sc gsi} utiliza
criptografia de chave pública, certificados X.509 e comunicação SSL (Secure
Sockets Layer) para estabelecer a identidade Globus do usuário. Por exemplo,
\texttt{C=US,O=University of California San Diego, OU=Grid Computing Lab,
  CN=Walfredo Cir\-ne} era uma identidade em Gusto (o primeiro Grid montado com
Globus). Depois do usuário ter se identificado junto ao {\sc gsi}, todos os
demais serviços Globus saberão, de forma segura, que o usuário é de fato quem
diz ser. Uma vez que um serviço sabe a identidade Globus do usuário, resta
estabelecer quais operações tal usuário pode realizar. Isto é feito mapeando a
identidade Globus para um usuário local. Por exemplo, o serviço {\sc gram} (veja
Seção~\ref{sec:gram}) instalado em {\em thing1.ucsd.edu} mapeava \texttt{C=US,
  O=University of California San Diego, OU=Grid Computing Lab,CN=Walfredo Cir\-ne}
para \texttt{walfredo}. Já o {\sc gram} que executava em {\em
  bluehorizon.sdsc.edu} mapeava \texttt{C=US, O=University of California San
  Diego, OU=Grid Computing Lab, CN=Walfredo Cir\-ne} para \texttt{u15595}.

Com a introdução da especificação {\sc ogsi}, a partir do Globus 3.0, novas
questões de segurança tiveram que ser abordadas, principalmente pela
convergência com Web Services. Ainda assim, vários padrões e especificações que
definem formatos para descrição de políticas de segurança, formatos para
delegação de credencial e autenticação e estabelecimento de comunicação segura,
puderam ser aproveitados no intuito de prover uma infraestrutura de segurança
para computação em Grids baseada em componentes
interoperáveis~\cite{grid-security}.

O objetivo principal do conjunto de serviços de segurança Globus, ilustrado na
Figura~\ref{fig:globus-arch} como a camada {\em GT3 Security Services}, é prover
transparência para os serviços das camadas de mais alto nível com relação à infraestrutura de segurança do Grid. 

\subsubsection{Descoberta e Alocação de Recursos}
\label{sec:gram}

Como discutimos na Seção~\ref{sec:schedAppvsRes}, Grids não têm um escalonador
que controla todo o sistema. Assim sendo, quando um usuário submete uma
aplicação para execução no Grid, o usuário utiliza um escalonador de aplicação
que escolhe os recursos a utilizar, particiona o trabalho entre tais recursos, e
envia tarefas para os escalonadores dos recursos, como ilustrado pela
Figura~\ref{fig:sched}.

{\sc gram} ({\em Globus Resource Allocation Manager}) é o serviço da arquitetura
Globus que fornece uma interface uniforme para submissão e controle de
tarefas~\cite{czajkowski-resource}, escondendo a multiplicidade de escalonadores
de recursos dos demais serviços de Grid (do escalonador de aplicações, por
exemplo). Além disso, {\sc gram} provê informações sobre o status do recurso ao
{\sc mds} (o serviço Globus que fornece informação sobre o Grid). 

\begin{figure}[htb]
\begin{center}
%\epsfig{file=Gram.eps,width=87mm,height=65mm}
\insimg{1}{imagens/Gram.png}
\caption{Arquitetura do {\sc gram}~\cite{czajkowski-resource}}
\label{fig:gram}
\end{center} 
\end{figure}

A Figura~\ref{fig:gram} permite um exame da arquitetura do {\sc gram}, que esclarece bastante sobre seus objetivos e funcionamento, através da identificação dos três componentes do {\sc gram} ({\em Gatekeeper, Job Manager e {\sc gram} Reporter}), bem como componentes externos que interagem com o {\sc gram}. O cliente {\sc gram} é aquele que o utiliza para submeter e controlar a execução de tarefas. Note que o cliente {\sc gram} pode ser um escalonador de aplicação ou até o próprio usuário. Para o cliente, a grande vantagem de usar {\sc gram} é a manipulação uniforme de tarefas, i.e. a submissão e controle de tarefas não importando qual é o escalonador de recurso
({\em Local Resource Manager, na Figura~\ref{fig:gram}}) usado para controlar a máquina. Isto é possível porque as requisições enviadas ao {\sc gram} são sempre escritas em {\sc rsl} ({\em Resource Specification Language}), independentemente de qual escalonador de recurso esteja sendo utilizado. O {\em Job Manager} é o responsável por converter a requisição em {\sc rsl} em um formato que o escalonador de recurso em questão entenda. Ao que sabemos, há versões do Job Manager para Condor~\cite{condor-hunter}, LoadLeveler~\cite{loadleveler}, PBS, Unix e Windows, entre outras plataformas.

%No Globus, os escalonadores de recurso são acessados através do serviço {\sc gram}. {\sc gram} fornece uma interface  única que permite submeter, monitorar
%  e controlar tarefas de forma independente do escalonador de
%  recursos. Portanto, escalonadores de aplicação não precisam entender dos
%  detalhes particulares de cada escalonador de recurso. Para facilitar ainda
%  mais a tarefa dos escalonadores de aplicação, Globus também disponibiliza {\sc
%  mds} (Metacomputing Directory Service), um serviço de informação sobre o
%  Grid. {\sc mds} contém informações sobre os recursos que formam o Grid e também
%  sobre seu estado (veja Seção~\ref{sec:descoberta}).

Uma idéia bastante interessante em Globus é que escalonadores de aplicação podem
usar os serviços de outros escalonadores de aplicação. O escalonador que recebe
a solicitação do cliente lida com a especificação em mais alto nível. Ele refina
tal especificação e, para implementá-la, submete novas solicitações a
escalonadores de recurso (que de fato executam solicitações) e/ou escalonadores
de aplicação (que utilizam outros escalonadores para executar solicitações).

Globus suporta bem esta hierarquia de escalonadores através da linguagem {\sc
  rsl}. {\sc rsl} é capaz de expressar tanto solicitação de alto nível (como a
que o usuário envia a seu escalonador de aplicações), como também solicitações
concretas (que são enviadas para {\sc gram}s, que as traduzem para escalonadores
de recurso locais). Portanto, o trabalho de um escalonador de aplicação em
Globus pode ser descrito como sendo o de refinar solicitações {\sc rsl}. A
Figura~\ref{fig:rsl} ilustra este processo no Globus 2.0. Note que Globus usa o
termo {\em broker} para o que chamamos de escalonador de aplicação. 

\begin{figure}[htb]
\begin{center}
%\epsfig{file=rsl.eps,width=136mm,height=92mm}
\insimg{1}{imagens/rsl.png}
\caption{Delegação entre escalonadores de aplicação~\cite{czajkowski-resource}}
\label{fig:rsl}
\end{center}
\end{figure}

Um componente importante para a execução de aplicações fortemente acopladas é o co-alocador ({\em Co-allocator}). O co-alocador é um escalonador de aplicação especializado em garantir que tarefas localizadas em máquinas distintas executem simultaneamente. Em aplicações fortemente acopladas, as tarefas precisam se comunicar para que a aplicação faça progresso. Portanto, todas as tarefas da aplicação têm que ser executadas simultaneamente. É importante ressaltar que uma boa implementação de co-alocação depende da implementação, por parte dos escalonadores de recurso, do serviço de reservas prévias ({\em advance reservation}). Reservas prévias permitem a escalonadores de aplicação obter garantias de escalonadores de recurso que determinados recursos (e.g. processadores) estarão disponíveis para aplicação em um intervalo de tempo preestabelecido~\cite{smith-scheduling}.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=schedexample.eps,width=126mm,height=94mm}
\insimg{1}{imagens/schedexample.png}
\caption{Exemplo do uso de escalonadores no Globus~\cite{czajkowski-resource}}
\label{fig:schedexample}
\end{center}
\end{figure}

A Figura~\ref{fig:schedexample} apresenta um exemplo da submissão de uma
aplicação em um Grid Globus. Veja que um usuário envia uma solicitação de
executar  uma simulação interativa envolvendo 100.000 entidades  para um
escalonador de aplicação especializado em simulação interativa distribuída. Tal
escalonador converte a solicitação original em outra mais especifica, que
descreve a necessidade do usuário em termos de ciclos, memória e latência de
comunicação. Esta nova solicitação é então enviada a um escalonador de aplicação
especializado em MPPs. Este escalonador consulta o {\sc mds} para descobrir quais MPPs
(dentro aqueles aos quais o usuário tem acesso) são os melhores para utilizar no
momento. Além disso, o escalonador especializado em MPPs faz a partição do
trabalho entre os MPPs escolhidos e envia a solicitação mais refinada para o
co-alocador. O co-alocador garante que as tarefas submetidas aos distintos MPPs
comecem a executar simultaneamente. Note também que outros escalonadores de
aplicações podem participar do sistema. A Figura~\ref{fig:schedexample}, por
exemplo, exemplifica ainda escalonadores para varredura de parâmetros e para
ambientes de colaboração virtual.

\subsubsection{Comunicação}

O problema de comunicação no Grid pode ser visto como uma instância do eterno
conflito entre generalidade e performance. Caso utilizemos um mecanismo de
comunicação genérico (e.g. TCP) que viabilize a comunicação fim-a-fim entre
quaisquer duas tarefas no Grid, perdemos performance em casos especiais (e.g. se
ambas tarefas rodam em uma máquina de memória compartilhada, elas poderiam se
comunicar muito mais rapidamente pela memória). Por outro lado, gostaríamos de
usar um mecanismo genérico para não ter que programar para cada uma das várias
tecnologias de comunicação existentes.

Globus ataca este problema com o Nexus~\cite{nexus-article}. Nexus fornece uma interface de
baixo nível, mas uma implementação adaptável que escolhe, dentre as tecnologias
de comunicação disponíveis, a que vai oferecer melhor performance. Por exemplo,
se ambas tarefas estão em uma máquina de memória compartilhada, Nexus utilizará
a memória para efetuar a comunicação. Caso as tarefas estejam em um MPP, Nexus
utilizará o switch de alta velocidade para comunicação. Caso as tarefas estejam
em máquinas geograficamente distantes, Nexus utilizará TCP/IP.

Nexus fornece uma interface de relativo baixo nível: invocação remota de
procedimento, mas sem retorno de resultado. Portanto, programar diretamente em
Nexus não é das tarefas mais agradáveis. Entretanto, a idéia da equipe Globus é
que Nexus seja usado por desenvolvedores de ferramentas e mecanismos de
comunicação, não diretamente pelo desenvolvedor de aplicações. MPI-G é o exemplo
perfeito desta abordagem. MPI-G implementa o popular padrão MPI (Message Passing
Interface) sobre Nexus. Assim, o desenvolvedor de aplicações escrever em MPI e
link-editar sua aplicação com MPI-G para automaticamente ter acesso a melhor
tecnologia de comunicação disponível (selecionada pelo Nexus).

\subsubsection{Transferência de Dados}

A necessidade de acesso remoto e transferência de dados é uma constante na
Computação em Grid. Na verdade, várias das aplicações aptas a executar no Grid
necessitam de paralelismo exatamente porque processam enormes quantidades de
dados. Ciente deste fato, Globus logo disponibilizou {\sc gass} (Global Access
to Secondary Storage)~\cite{bester-gass}, um serviço para acesso remoto a
arquivos sob a tutela de um servidor {\sc gass}. O cliente {\sc gass} é uma
biblioteca C que é link-editada à aplicação usuária do serviço. Com o intuito de
fornecer boa performance, o serviço GASS implementa as otimizações típicas de
acesso remoto como caching e pre-fetching.

Apesar de ser um bom serviço, o {\sc gass} encontrou problemas de implantação. A
dificuldade encontrada foi de interoperabilidade. A maioria das fontes de dados
onde se instalaria um servidor GASS já executa algum serviço de transferência
e/ou acesso remoto a arquivos. Os administradores de sistema se questionavam
então porque não se poderia usar os serviços existentes. Essa realidade motivou
a introdução do GridFTP~\cite{allcock-gridftp} por parte da equipe
Globus. GridFTP estende o popular protocolo FTP para torná-lo mais adequado para
as necessidades da Computação em Grid. Mais precisamente, GridFTP introduz
suporte a: 

\begin{itemize}

  \item Autenticação {\sc gsi} e Kerberos
  \item Transferência em paralelo (várias conexões TCP entre fonte e destino)
  \item Transferência striped (conexões TCP entre várias fontes e um destino, ou vice-versa) 
  \item Controle manual dos buffers TCP (usado para afinamento de performance)
  \item Instrumentação embutida 

\end{itemize}

Uma vez que GridFTP é uma extensão do FTP, o problema de interoperabilidade fica
resolvido, pois FTP é amplamente suportado pelos servidores de
dados. Obviamente, se as extensões GridFTP não estiverem implementadas em um
dado servidor, os benefícios adicionais do protocolo não estarão disponível. Mas
o cliente GridFTP ainda será capaz de obter os dados desejados. Ou seja, o
sistema será penalizado apenas no desempenho, porém continuará funcionando.

\subsubsection{Avaliação do Globus}

Um aspecto importante para grande aceitação do Globus é que os serviços
oferecidos são razoavelmente independentes, possibilitando que se utilize apenas
parte dos serviços Globus em uma dada solução. Essa possibilidade do uso parcial
de Globus ajuda sobremaneira na adaptação de aplicações paralelas existentes
para o Grid. Pode-se começar usando serviços mais básicos e ir, aos poucos,
incorporando funcionalidades mais a\-van\-ça\-das. O design oposto à abordagem
conjunto de serviços independentes  do Globus é exemplificado pelo
Legion~\cite{legion-virtual}. Legion fornece um modelo orientado a objetos
poderoso e flexível. Entretanto, o usuário tem que utilizar a solução Legion de
forma integral, sem estágios intermediários. Esta diferença de abordagem talvez
tenha contribuído para prevalência do Globus como padrão {\em de facto} de
infraestrutura para Computação em Grid. É interessante notar que a decisão de
estruturar Globus como um conjunto de serviços independentes deixa claro que
Globus não é uma solução pronta e completa ({\em plug-and-play}) para construção
de Grids. Globus certamente fornece serviços úteis para Computação em
Grids. Mas, desenvolvedores, administradores e usuários precisam despender certo
esforço para finalizar seu Grid. Por exemplo, administradores precisam decidir
quais usuários terão acesso a quais recursos que compõem o Grid e em quais
condições este acesso se dará (veja Seção~\ref{sec:gram}). Em outro exemplo,
freqüentemente é necessário desenvolver escalonadores de aplicação (veja
Seção~\ref{sec:sched}) que tenham conhecimento sobre as aplicações que serão
executadas e algumas vezes também sobre a estrutura do Grid a ser usado. 

Computação em Grid é simplesmente muito complexa para possibilitar soluções
plug-and-play. Portanto, o fato do Globus não ser uma solução pronta e completa
não é nenhum demérito. Entretanto, algumas pessoas têm a idéia de que Globus é a
solução, completa e perfeita. Esta falsa concepção, sim, é um problema pois gera
falsas expectativas e obscurece discussões técnicas com alegações de marketing.

Vale ressaltar que a discussão apresentada nas seções anteriores é válida para o
Globus 2.0. Ainda se torna pertinente apresentar as características do Globus
2.0, pois muitos grupos interessados em computação de alto desempenho utilizam
infraestruturas baseadas no GT2 (Globus Toolkit 2.0). 

A introdução do padrão {\sc ogsa} criou um alinhamento com tecnologias e padrões Web Services, assim vários desses aspectos discutidos anteriormente se modificaram em busca da implementações de padrões que promovem maior interoperabilidade. 

A arquitetura do Globus Toolkit 3 é ilustrada pela Figura~\ref{fig:globus-arch}. Essa versão é uma implementação da especificação {\sc ogsi} ({\em Open Grid Services Infrastructure})~\cite{ogsi-spec}, os serviços implementados na camada {\em GT3 Core Services} representam os serviços especificados pela {\sc ogsi}. O objetivo é especificar mecanismos para criação, gerenciamento e troca de dados entre Grid Services.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=gt3_arch.eps,width=35mm,height=48mm}
\insimg{1}{imagens/gt3_arch.png}
\caption{Arquitetura do Globus~\cite{gt3-tutorial}}
\label{fig:globus-arch}
\end{center}
\end{figure}

Como discutimos nas Seções~\ref{sec:gt3} e~\ref{sec:gt4}, há uma tendência forte de convergência entre as tecnologias de Grids Computacionais e Web Services. Isso fica claro com a introdução da especificação {\sc wsrf}, que posiciona as tecnologias de Grids junto aos padrões para Web Services.

\subsection{MyGrid}
\label{sec:mygrid}

A motivação para a construção do MyGrid surgiu do fato que, embora bastante
pesquisa tenha sido realizada para o desenvolvimento dos Grids Computacionais,
poucos usuários executavam suas aplicações paralelas sobre essa
infraestrutura. Assim, foi concebido projeto MyGrid, com o intuito de alterar esta
situação. Para tanto, foram atacadas apenas aplicações Bag-of-Tasks, ou seja, aquelas
aplicações cujas tarefas são independentes, podendo ser executadas em qualquer
ordem. Aplicações Bag-of-Tasks são um alvo interessante porque (i) se adequam
melhor a ampla distribuição, heterogeneidade e dinamicidade do Grid, e (ii)
resolvem vários problemas importantes, tais como mineração de dados,
processamento genômico, pesquisa massiva (como quebra de chaves
criptográficas), varredura de parâmetros, simulações Monte Carlo (muito
utilizado, por exemplo, pela indústria farmacéutica~\cite{karen-lock}),
computação de fractais (como Mandelbrot), e manipulação de imagem (como
tomografia). 

%Para um usuário do MyGrid, o Grid é composto por todas as máquinas que o usuário
%pode acessar diretamente e as máquinas que ele pode obter da comunidade através
%do peer OurGrid~\cite{ourgrid-site,andrade-ourgrid} (ver
%Seção~\ref{sec:ourgrid}). Sendo assim, o Grid de um dado usuário pode conter as
%máquinas de seu laboratório, de outros laboratórios com que o usuário desenvolve
%atividades conjuntas, de algum provedor contratado para fornecer ciclos, e até
%de algum amigo que forneceu um login para sua máquina. Note que a decisão de
%definir Grid em função do que o usuário pode acessar se afina bem com o fato de
%suportarmos aplicações Bag of Tasks. Devido à fraca acoplamento entre as tarefas
%de uma aplicação Bag of Tasks, o usuário pode em principio se beneficiar de
%quaisquer processadores que ele tenha acesso.  

Estabelecido o escopo do MyGrid, nosso objetivo é construir um sistema simples,
completo e seguro. Por simples queremos dizer que o esforço para utilização do
MyGrid deve ser mínimo. Em particular, queremos chegar o mais próximo possível
de uma solução pronta (plug-and-play). Por completo denotamos a necessidade de
cobrir todo o ciclo de uso de um sistema computacional, do desenvolvimento à
execução, passando por instalação e atualização e incluindo também a manipulação
de arquivos. Por seguro expressamos a necessidade de não introduzir
vulnerabilidades ao ambiente computacional do usuário. Ou seja, não queremos que
falhas de segurança em qualquer uma das máquinas que o usuário possa utilizar
sejam propagadas para sua máquina base (i.e. o computador usado pelo usuário).

MyGrid diferencia entre máquina base e máquina do Grid. Em um MyGrid, a máquina
base é aquela que controla a execução da aplicação. Ela tipicamente contém os
dados de entrada e coleta os resultados da computação. A máquina base é
normalmente usada pelo usuário diretamente no seu dia-a-dia, muitas vezes sendo
o próprio computador desktop do usuário. Esperamos, portanto, que o usuário
tenha excelente acesso à máquina base e que tenha customizado um ambiente de
trabalho confortável nela. 

Todas as máquinas usadas via MyGrid para executar tarefas são chamadas de
máquinas de grid. Ao contrário da máquina base, não assumimos que o usuário
customizou cada máquina do Grid para criar-lhe um ambiente de trabalho
familiar. Além disso, todas as máquinas do Grid tipicamente não compartilham um
mesmo sistema de arquivo ou têm os mesmos softwares instalados. A imagem do
sistema pode variar de uma máquina do Grid para outra. Portanto, para mantermos
a simplicidade de uso do sistema, precisamos evitar que o usuário tenha que
lidar diretamente com as máquinas do Grid. Por exemplo, queremos evitar que o
usuário tenha que instalar software em cada máquina de seu Grid. A idéia é que
máquinas do Grid sejam manipuladas através das abstrações criadas por MyGrid
(descritas a seguir).

Um aspecto importante de MyGrid é dar ao usuário a possibilidade de usar  quaisquer recursos que ele tenha acesso . Este
não é um objetivo trivial porque ele implica que temos que assumir muito pouco a respeito de uma máquina do Grid, de
forma a não impedir algum usuário de usar uma máquina que não suporta nossas hipóteses. Em particular, não podemos
assumir que tal recurso tenha software MyGrid instalado. MyGrid define {\em Grid Machine Interface} como sendo o
conjunto mínimo de serviços que precisam estar disponíveis para que uma dada máquina possa ser adicionada ao Grid do
usuário. Tais serviços são:

\begin{table}[htb]
\scriptsize
\centering
\begin{tabular}{|c|}\hline
{\bf Serviços} \\\hline
Execução remota \\\hline
Transferência de Arquivo (Máquina Base $\mapsto$ Grid Machine) \\\hline
Transferência de Arquivo (Grid Machine $\mapsto$ Máquina Base) \\\hline
Interrupção de uma Execução múltipla \\\hline
\end{tabular}
\normalsize
\caption{Grid Machine Interface}\label{tab:gum}
\end{table}

\begin{figure}[htb]
\begin{center}
%\epsfig{file=MGArchitecture.eps,width=125mm,height=78mm}
\insimg{1}{imagens/MGArchitecture.png}
\caption{Arquitetura do MyGrid}
\label{fig:gumimpl}
\end{center}
\end{figure}

Como ilustrado pela Figura~\ref{fig:gumimpl}, há várias formas de implementar os
serviços oferecidos através da {\em Grid Machine Interface}. Uma forma é
fornecer ao sistema scripts que implementam os serviços listados na
Tabela~\ref{tab:gum}. Neste caso, MyGrid utiliza o módulo Grid Script para
acessar a má-quina em questão. Note que Grid Script possibilita que, qualquer
que seja a máquina que o usuário tem acesso, ele possa informar como este acesso
se dá através da escrita de três scripts. Alternativamente, há casos em que a
forma de acessar uma determinada máquina do Grid já é do conhecimento do
MyGrid. Por exemplo, suponha que a máquina em questão pode ser acessada via
serviços Globus ({\sc gsi}, {\sc gram} e GridFTP). Neste caso, o usuário não precisa
fornecer os scripts, indicando apenas que o acesso à máquina já é conhecido de
MyGrid. Finalmente, MyGrid também provê um mecanismo de acesso a máquinas do
Grid, chamado de User Agent. O User Agent provê serviços simples. É interessante
notar que, pela terminologia adotada por Foster, et
al.~\cite{foster-physiology}, {\em Grid Machine Interface} é uma{\em
  virtualização} para os serviços de acesso a uma máquina do Grid.

Outro componente fundamental a arquitetura MyGrid é o {\em Scheduler}. O
Scheduler recebe do usuário a descrição das tarefas a executar, escolhe qual
processador usar para cada tarefa, e finalmente submete e monitora a execução da
tarefa. O MyGrid possui atualmente duas heurística de escalonamento: Workqueue
with Replication ({\sc wqr})~\cite{paranhos-trading} e Storage
Affinity~\cite{santos-neto-exploiting}. Ambas, conseguem obter uma boa
performance mesmo sem utilizar informações sobre o estado do Grid ou o tamanho
de cada tarefa (ver Seção \ref{sec:wqr} e Seção~\ref{sec:affinity}). O {\sc wqr}
foi definido para aplicações {\em cpu-intensive}, enquanto Storage Affinity foi
desenvolvido para melhorar o desempenho de aplicações que processam grandes
quantidades de dados.

Note que ter um algoritmo de escalonamento que funciona bem sem depender de
muita informação é importante, pois simplifica a definição da {\em Grid Machine
  Interface}. Caso o algoritmo de escalonamento do MyGrid necessitasse de
informações sobre as máquinas do Grid, {\em Grid Machine Interface} teria que
ser mais rica e, portanto, mais difícil de virtualizar. Por exemplo, o
Nimrod-G~\cite{buyya-nimrodg} define uma interface de abstração para os
recursos, que contempla métodos de fornecimento de informação sobre o
recurso. Certamente, a informação obtida por esses métodos é valiosa para o
escalonamento eficiente das aplicações. Porém, isso limita o tipo de recurso que
pode ser utilizado, pois torna o {\em middleware} dependente de um recurso que
forneça uma implementação para os métodos dessa interface. 

Uma aplicação (ou Job) MyGrid é composta de tarefas independentes. Estas tarefas
são compostas por três partes ou sub-tarefas: {\em init, remote} e {\em
  final}. As sub-tarefas são executadas seqüencialmente ($init \mapsto remote
\mapsto final$). As sub-tarefas {\em init} e {\em final} são usadas para efetuar
as transferências de arquivo de entrada e saída da tarefa respectivamente. Sendo
assim, tanto a sub-tarefa inicial quando a final são executadas na máquina
base. Enquanto, a sub-tarefa {\em remote}, como o próprio nome sugere, é
executada em uma máquina do Grid e realiza a computação propriamente dita da
tarefa.

Para definir as sub-tarefas inicial e final, o usuário tem disponível algumas
abs\-tra\-ções providas pelo MyGrid para lidar com a máquina do Grid sem necessitar
de conhecer sua imagem do sistema. As abstrações providas pelo MyGrid são {\em
  storage} e {\em playpen}. O serviço de {\em storage} possui a semântica de uma
área de armazenamento persistente à execução da tarefa. Ou seja, é útil usar
{\em storage} para distribuição de arquivos que provavelmente serão reutilizados
no Grid (ex.: executáveis da aplicação). Assim sendo, qualquer arquivo
transferido para o {\em storage} é automaticamente incluído no PATH da máquina
do Grid. Por outro lado, o {\em playpen} provê uma área de armazenamento
temporária de maneira independente das convenções locais do sistema de arquivo
de uma dada máquina do Grid. Essa área de armazenamento temporária é criada
automaticamente e é o diretório base de execução da sub-tarefa {\em
  remote}. Note que o playpen foi concebido para possibilitar o armazenamento
de dados temporários e resultados de tarefas. Também no sentido de simplificar a
escrita das sub-tarefas, as variáveis de ambiente {\sc \$storage}, {\sc
  \$playpen}, {\sc \$proc} e {\sc \$task} são automaticamente definidas pelo
MyGrid e contêm, respectivamente, o caminho completo para área de {\em storage},
o caminho completo para o {\em playpen} de uma dada tarefa, o nome da máquina do
Grid escolhida para executar a tarefa e um identificador da tarefa.

\subsection{OurGrid}
\label{sec:ourgrid}

Ao contrário do Globus, a solução OurGrid tem um escopo diferente, porém complementar. O objetivo é prover uma solução efetiva para a execução de aplicações Bag-of-Tasks em Grids Computacionais. Sendo assim, as decisões de projeto estão centradas no uso da solução em ambientes de produção. Portanto, a idéia básica é abdicar da generalidade, em alguns casos, no intuito de se obter uma solução, apesar de simples, eficiente e que possa ser facilmente usada em produção.

A arquitetura do OurGrid, brevemente comentada na Seção~\ref{sec:rede} e
ilustrada na Figura~\ref{fig:nof}, é formada por três componentes: MyGrid Broker
(ver Seção~\ref{sec:mygrid}), OurGrid Peer e uma solução de sandboxing baseada
na máquina virtual Xen~\cite{xen-art}. Nas seções seguintes descreveremos como
os componentes do OurGrid abordam alguns aspectos importantes da Computação em Grid.

\subsubsection{Autenticação}

Na arquitetura OurGrid existem basicamente dois níveis de autenticação. Esses
níveis dependem de como o usuário obteve o recurso. Primeiramente, o usuário
pode ter acesso direto a alguns recursos (i.e. {\em Grid Machines} - {\sc GuM}s - em sua rede local), neste caso o usuário usa o esquema de autenticação tradicional, em geral, isso implica na utilização da infraestrutura de autenticação do sistema operacional do recurso, ou seja, nome de usuário ({\em login}) e uma senha. 

Contudo, além das {\sc GuM}s que o usuário tem acesso direto, OurGrid permite (e promove) a obtenção de acesso a {\sc GuM}s de outros sites, isso ocorre através de um OurGrid Peer local ao site do usuário. Este peer deve estar conectado à rede de favores (ver Figura~\ref{fig:nof}). Assim, para as {\sc GuM}s obtidas da comunidade, há uma autenticação em duas vias baseada em certificados digitais no formato X.509. A primeira parte da autenticação deve garantir que o usuário tem permissão para solicitar serviços às {\sc GuM}s (i.e. que a GuM conhece o usuário que está requisitando seus serviços). A segunda parte deve garantir que o usuário não está solicitando serviços a uma falsa {\sc GuM}. Ou seja, tanto o usuário, através do broker, quanto os peers da comunidade possuem uma lista de certificados que são usadas para validar a tentativa de aceso.

Isso impede que usuários não autorizados pelo peer, obtenham acesso aos serviços de descoberta de novas Grid Machines, transferência de arquivos, execução e gerenciamento do ciclo de vida de replicas fornecido pelas {\sc GuM}s controladas por um dado peer.

Outro aspecto importante é que através da utilização de certificados, a comunicação entre o MyGrid Broker, o peer e as Grid Machines será segura, evitando que os dados sejam interceptados e manipulados durante a comunicação. A segurança na comunicação é fornecida através do uso de {\sc rmi} baseado em {\sc ssl} ({\em Secure Socket Layer}), que garante comunicação criptografada.

\subsubsection{Descoberta e Alocação de Recursos}

Para executar uma aplicação usando a OurGrid o usuário deve descrever sua aplicação e o conjunto de recursos que o usuário tem acesso. Note que esse conjunto de recursos pode ser apenas a indicação de um OurGrid Peer, que tem a função de obter recursos para o usuário.

A descrição da aplicação é basicamente: um conjunto tarefas, seus arquivos de entrada, arquivos de saída e seus requisitos (e.g. sistema operacional necessário, mínimo de memória, arquitetura do processador). Em seguida, o usuário o submete sua aplicação para execução no Grid através do MyGrid Broker. O componente interno do MyGrid Broker que recebe a submissão é o {\em Scheduler}. Por sua vez, o Scheduler requisita aos provedores de {\sc GuM}s recursos para executar a aplicação submetida pelo usuário. Esses provedores podem responder com recursos locais ou recursos obtidos na rede de favores. Para que o Scheduler receba uma resposta dos provedores é necessário que tenha sido encontrada uma {\sc GuM} que preenche os requisitos determinados na descrição da aplicação.

Portanto, após ter sido descoberto um recurso que possui atributos compatíveis com os requisitos da aplicação, o recurso é alocado e repassado para o Scheduler que o solicitou. Certamente, isso só irá ocorrer caso o recurso esteja disponível. Porém, caso o recurso tenha sido descoberto através da rede de favores, o recurso pode ser tomado de volta (i.e. preemptado) pelo peer que o forneceu, seguindo a dinâmica da rede de favores. A preempção é um evento natural e previsto pela arquitetura do OurGrid, uma vez que os recursos só são cedidos caso esteja ocioso. Ou seja, uma solicitação local no site, ao qual o recurso pertence, pode ocasionar a preempção. 

Vale também ressaltar que a alocação do recurso é feita no nível do MyGrid Broker, ou seja, isso não significa que o recurso estará dedicado exclusivamente ao MyGrid Broker. Portanto, não há impedimento para que outras aplicações que não usam a infraestrutura do OurGrid estejam executando concorrentemente com a aplicação submetida pelo usuário.

\subsubsection{Comunicação}

Uma vez que o foco da solução OurGrid está nas aplicações Bag-of-Tasks, não faz parte do escopo da solução OurGrid prover mecanismos de comunicação para aplicações fortemente acopladas. Mesmo assim, é possível usar a infraestrutura OurGrid para executar aplicações deste tipo, desde que a execução seja interna a um site. Por exemplo, uma aplicação que usa MPI, quando descrita pelo usuário, pode ter especificado em seus requisitos que necessita de uma {\sc GuM} (Grid Machine), que na verdade é o {\em front end} de uma coleção de vários processadores (i.e. um cluster). Essa demanda será atendida se existir uma GuM, não alocada, que possua um atributo compatível com o requisito especificado pela aplicação. Portanto, apesar de não ter uma arquitetura que provê comunicação entre as tarefas que estão sendo executadas nas GuMs, a solução OurGrid provê meios de agregar ao Grid GuMs que permitem a execução de aplicações fortemente acopladas. 

\subsubsection{Transferência de Dados}

A solução OurGrid para transferência de dados é baseada no tratamento de arquivos. Desta forma, o usuário ao descrever sua aplicação tem a sua disposição o uso de três operações de transferência arquivos, {\texttt put}, {\texttt store} e {\texttt get}, que podem ser usadas para preparar o ambiente para execução da aplicação (colocando os arquivos nos sites onde a aplicação irá executar), como também coletar os dados resultantes do processamento. 

Tanto {\texttt put} quanto {\texttt store} são operações que permitem a transferir arquivos {\em para} a GuM. A diferença entre as duas operações consiste apenas do fato que {\texttt store} evita a transferência do arquivo caso o arquivo já se encontre armazenado no lado remoto. Isso é útil, por exemplo, para executáveis da aplicação e dados que são reutilizados entre execuções sucessivas da aplicação. A terceira operação, {\texttt get}, fornece um método de coletar arquivos resultantes da execução das aplicações.

A infraestrutura de comunicação usada para a transferência é a mesma usada para a solicitação de serviços de execução, ou seja, RMI. Uma vez que é possível ter segurança na comunicação com as GuMs de RMI sobre SSL, as operações de transferências de dados também gozam da segurança fornecida pela camada de comunicação baseada em certificados. 

\subsubsection{Avaliação do OurGrid}

A característica mais importante do OurGrid é conseguir prover uma solução útil e eficiente para uma comunidade de usuários em produção, apesar de se basear em soluções simples e de escopo limitado (i.e. apenas aplicações do tipo Bag-of-Tasks).

É importante notar que o objetivo do OurGrid contrasta com o objetivo do Globus, que fornece um conjunto de serviços para a construção da infraestrutura do Grid. Portanto,  OurGrid é uma solução que complementa o Globus provendo um broker (i.e. MyGrid) e abstrações que permitem o usuário usar recursos Globus e não-Globus. Por outro lado, Globus complementa o OurGrid ao fornecer a infraestrutura de serviços para execução de aplicações em larga escala.

%Outras alternativas para computação em Grid tem objetivos semelhantes ao
%OurGrid. Por exemplo, Condor e Nimrod são projetos que fornecem mecanismos que
%permite o usuário executar sua aplicação em recursos amplamente
%dispersos. Porém, a vantagem do MyGrid sobre estas alternativas é o fato de
%exigir o mínimo da infraestrutura que o usuário tem acesso. Isso significa dizer
%que OurGrid não requer nenhum software específico, ou mesmo que a aplicação do
%usuário seja modificada para executar. 

OurGrid persegue um objetivo diferente do que seria prover uma solução genérica para computação em Grid. Com o foco em aplicações BoT foi possível produzir uma solução efetiva para uma comunidade de usuários em produção. Não se quer dizer com isso que não se pretende introduzir novas funcionalidades, que aumentem o escopo da solução. Ao contrário, a idéia é gradativamente permitir que mais aplicações possam utilizar a solução. Por exemplo, suporte a {\em workflow},
suporte a {\em data-mining}, etc.

Atualmente na versão 3.0.2, OurGrid já é usado em produção por vários grupos de pesquisa no Brasil~\cite{cirne-paua}. As próximas versões prometem incorporar melhorias no escalonamento de aplicações, solução de sandboxing, bem como maior tolerância para aplicações de longa duração ({\em high-throughput computing}) através do uso de {\em checkpoint}. O software OurGrid está disponível para download em {\em http://www.ourgrid.org}.

\subsection{Condor}
\label{sec:condor}

De forma semelhante ao OurGrid, Condor é uma sistema que possui um escopo bem definido e menos genérico que outras soluções para computação de alto desempenho em Grids Computacionais. Condor objetiva fornecer grande quantidade de poder computacional a médio e longo prazo (dias a semanas) utilizando recursos ociosos na rede~\cite{condor-hunter}. Os autores do sistema salientam insistentemente que Condor objetiva alta vazão ({\em high throughput}) e não alto desempenho ({\em high performance})~\cite{basney-deploy,condor-flock,frey-condor-g,condor-hunter}. Entenda-se disto que Condor visa fornecer desempenho sustentável a médio e longo prazos, mesmo que o desempenho instantâneo do sistema possa variar consideravelmente.

%O usuário submete ao Condor tarefas independentes para execução. Isso significa
%que uma aplicação Condor é uma aplicação Bag-of-Tasks. Aparentemente isso limita
%em demasiado as aplicações que podem ser executadas em Condor, contudo deve-se
%salientar que há um grande número de aplicações importantes que são compostas de
%tarefas independentes. Além disso, aplicações Bag-of-Tasks, devido ao seu fraco
%acoplamento, são bastante adequadas para execução em Grids Computacionais.

Condor foi inicialmente concebido para funcionar em {\sc NoW}s ({\em Network of Workstations}). Uma {\sc NoW} que executa Condor denomina-se {\em Condor Pool}. O elemento arquitetural mais importante de um Condor Pool é o {\em Matchmaker}. O Matchmaker aloca tarefas a máquinas pertencentes ao Pool. Tal alocação é baseada nas necessidades de cada tarefa e nas restrições de uso de cada máquina. As necessidades de uma tarefa são especificadas pelo usuário quando de sua submissão. Por exemplo, uma tarefa pode precisar de uma máquina Sun Sparc, rodando Solaris, com pelo menos $256MB$ de memória. Já as restrições de uso de uma dada máquina, estas são especificadas por seu dono quando da inclusão da máquina no Pool. Por exemplo, o dono pode preferir que sua máquina execute as aplicações de João, seguido das aplicações do grupo de sistemas operacionais, e que nunca execute as aplicações de Pedro. Ou seja, as restrições permitem ao dono determinar como sua máquina será usada no Condor Pool. Tipicamente, o dono estabelece também que sua máquina só é usada quando estiver ociosa e que, quando ele voltar a utilizar a máquina, qualquer aplicação Condor em execução seja suspensa imediatamente. 

Um aspecto interessante do Condor é que ambos usuários e donos de máquinas são representados no sistema por agentes de software. O {\em Customer Agent} (Agente do Usuário) envia as necessidades da tarefa para o Matchmaker. De forma similar, {\em Resource Owner Agent} envia as restrições de uso do recurso ao Matchmaker. Ao efetuar o casamento de padrões entre tarefa os requisitos da tarefa e os atributos da máquina, o Matchmaker notifica ambos Agentes. A partir daí, os Agentes interagem diretamente para realizar a execução da tarefa. A Figura~\ref{fig:condorprotocol} ilustra este protocolo.

\begin{figure}[htb]
\begin{center}
%\epsfig{file=CondorProtocol.eps,width=60mm,height=45mm}
\insimg{1}{imagens/CondorProtocol.png}
\caption{Condor protocol~\cite{basney-deploy}}
\label{fig:condorprotocol}
\end{center}
\end{figure}

Outro aspecto atraente do Condor é seu mecanismo de {\em checkpointing}. Uma vez que o dono normalmente especifica que sua máquina seja  desocupada  pela tarefa Condor assim que ele retornar a usá-la, garantir progresso das tarefas torna-se um problema não-trivial. Condor aborda esta questão fazendo o checkpoint da tarefa (i.e. salvando transparentemente o estado de sua execução). Isto permite que a tarefa seja reexecutada em outra máquina a partir do ponto em que parou. Vale salientar que o mecanismo de checkpoint do Condor é implementado através da substituição da biblioteca do sistema por uma biblioteca Condor. 

%Note, portanto,
%que o mecanismo de checkpointing é implementado em conjunto com o mecanismo de
%redirecionamento de acesso a arquivos. Na verdade, acesso aos arquivos na
%máquina base e migração de tarefas são complementares. De que adiantaria migrar
%tarefas se elas estivessem acessando o sistema de arquivos local? 

Condor foi posteriormente estendido para execução em Grids~\cite{condor-flock,frey-condor-g}. É interessante notar que Condor dispõe de duas formas de funcionamento em Grids: Flock of Condors~\cite{condor-flock} e Condor-G~\cite{frey-condor-g}.

Flock of Condors é um trabalho que antecede Condor-G. Um Flock of Condors é um Grid formado por vários Condor Pools~\cite{condor-flock}. A construção do Flock é bastante elegante do ponto de vista de sistemas distribuídos pois não acrescenta nenhuma centralização a arquitetura Condor original. A base para criação de um Flock é um acordo de cooperação (de troca de recursos) entre dois Condors Pools. Portanto, por maior que seja o Flock, suas ligações são sempre dois-a-dois, sem envolver nenhuma entidade centralizadora. Mais que isso, o Flock of Condors não chega a alterar o software Condor original. Todo a funcionalidade do Flock of Condors é implementada por uma máquina especial, chamada Gateway. Ambos os Pools que firmam um acordo de cooperação instalam cada qual um Gateway. Os dois Gateways mantém comunicação constante para troca de tarefas entre os Pools. Para o Pool local, o Gateway é uma máquina qualquer. Entretanto, ao invés de oferecer seus próprios recursos, o Gateway simplesmente representa os recursos do Pool remoto, republicado as restrições estabelecidas pelos donos das máquinas remotas. Quando uma tarefa é recebida pelo Gateway, este a repassa para o Gateway remoto que então a encaminha para uma máquina do pool remoto.

Talvez por ser mais recente, o Condor-G adota uma visão mais heterogênea de Grid. Além de Condor Pools, Condor-G também utiliza recursos via Globus. Devido à necessidade de suportar mais heterogeneidade, Condor-G usa uma arquitetura mais centralizada que o Flock of Condors. O Condor-G Scheduler controla a execução da aplicação, submetendo tarefas tanto a Condor Pools quanto a recursos acessíveis via Globus (como MPPs). No caso de recursos Globus, Condor-G utiliza
os serviços {\sc gram}, GASS, {\sc mds} e {\sc gsi} para viabilizar a execução das tarefas.

\clearpage
%%%Rodrigo
\section{Integração de clusters em grids}
\label{integracaodeclusteregrids}
%\cutname{integracaodeclusteregrids.html}

Clusters são um tipo de recurso de especial interesse para usuários de grids,
devido à enorme capacidade computacional que são capazes de fornecer.
Porém, a utilização dos clusters não é uma tarefa trivial, devido a características
inerentes ao sistema.

Clusters (em especial os de alto desempenho) são comumente utilizados através
de gerenciadores de recursos. Estes gerenciadores controlam a fila de acesso, os
direitos de acessos dos usuários e coordenam o uso dos recursos, garantindo que
somente usuários autorizados acessem os recursos, na quantidade a que têm
direito e pelo tempo igualmente permitido.

Para um usuário ser capaz de especificar uma quantidade de máquinas e um tempo
de utilização das mesmas, ele precisa conhecer a sua aplicação e a capacidade das
máquinas, a fim de estabelecer um tempo de utilização razoável. Se o tempo for
subestimado, a aplicação não completará antes do usuário perder o direito de acesso
aos recursos, desperdiçando a utilização do recurso (pois o uso de mecanismos de
retomada de aplicações parcialmente executadas não é difundido em todas as
comunidades de usuários de aplicações de alto desempenho). Se o tempo for
superestimado, o início da execução da aplicação tende a ser postergado (por
características dos algoritmos de escalonamento comumente utilizados pelos
gerenciadores, que tendem a encaixar requisições ``menores'' em espaços de
alocação que não são suficientes para atender as requisições maiores, adiantando
as primeiras).

Em grids, o problema da dificuldade de estabelecer o tempo de execução aumenta,
pois é possível que o usuário sequer conheça a capacidade das máquinas que irá receber.

Além deste problema, existe um outro fator prejudicial à utilização de clusters
em grids, que é o fato de diferentes gerenciadores de clusters possuirem diferentes
linguagens de requisições. Isto exige que exista um componente entre o grid e o cluster
(chamado de \emph{conector}) capaz de prover uma linguagem única sobre a qual
requisições do grid podem ser enviadas de forma padronizada, tendo este componente
a função de converter estas requisições para a linguagem específica do gerenciador
utilizado no determinado cluster (Figura \ref{fig:grid-cluster}).


\begin{figure}[htb]
\begin{center}
\insimg{1}{imagens/conector-grid-cluster.png}
\caption{Utilização de clusters em grids.}
\label{fig:grid-cluster}
\end{center}
\end{figure}

\subsection{Globus GRAM}

Um destes componentes capaz de converter requisições de grid para clusters
específicos é o GRAM (Grid Resource Allocation and Management) do Globus.
Ele recebe as requisições (RSL -- Resource Specification Language) e é capaz de
convertê-las para gerenciadores específicos.

No entanto, um GRAM é capaz de atender um único recurso. No contexto do
GRAM, um recurso pode ser um cluster gerenciado por um gerenciador de
recursos específico, ou pode ser uma única máquina ou um conjunto de máquinas
gerenciadas pelo Condor.

Se um determinado local contar com mais de um recurso, deverá existir um GRAM
para controlar cada um.

\subsection{Alocação transparente de recursos}

Uma técnica que pode ser empregada para evitar que usuários tenham que
especificar o tempo e o número de máquinas que desejam utilizar, além de
ser menos invasivo do ponto de vista da utilização do cluster é a técnica de
alocação transparente, apresentada originalmente em \cite{aloctransp}.

A técnica pode ser utilizada quando a aplicação a ser executada no grid é
composta de tarefas independentes (como por exemplo aplicações
\emph{Bag}-\emph{of}-\emph{Tasks}). Com o seu uso, não é necessário que
sejam alocadas máquinas para que usuários de grid possam executar suas tarefas:
todas as máquinas que não estão em uso por usuários locais são disponibilizadas
à grade, e ficam disponíveis para a execução de tarefas até que sejam requisitadas
por usuários locais (isto é, usuário que possuem direito de acesso ao recurso),
momento em que são retiradas da grade e alocadas a tal usuário.

Como esta técnica é utilizada para a execução de tarefas independentes, o
cancelamento súbito da tarefa não causará falha na execução da aplicação: ela
apenas será atrasada, uma vez que a tarefa deverá ser re-escalonada e re-executada desde
o seu início. Se a aplicação (ou o grid) oferecer algum tipo de mecanismo de
retomada de execução de tarefas (por exemplo, \emph{checkpointing}), o
tempo de atraso da aplicação será menor.

Dependendo do modelo de utilização do cluster, esta técnica pode apresentar
melhor tempo de execução de tarefas de grade do que outras heurísticas, ao mesmo
tempo em que se mostra menos invasiva ao cluster: usuários locais não deixarão de
utilizar estes recursos devido a presença de tarefas da grade, o que pode incentivar
administradores de clusters a cederem o seu cluster (em especial, os seus ciclos
ociosos) para o grid.

A técnica é atualmente aplicada com sucesso para integrar clusters na comunidade OurGrid.

Formas como tal heurística pode ser implementada na prática, avaliação da técnica
sobre alguns cenários, mostrando o seu desempenho e outras considerações sobre a
Alocação Transparente podem ser encontradas em \cite{aloctransp}.
%%%Rodrigo


\section{Tendências em Grids Computacionais}
\label{sec:future}
%\cutname{gridstendencias.html}

Neste capítulo foi apresentando os principais aspectos dos Grids Computacionais,
desde a apresentação de um conceito do que classifica uma infraestrutura de
computação distribuída como um Grid Computacional, até o estado atual do
desenvolvimento de tecnologia para a construção dessas infraestruturas.

Vimos que Grids Computacionais levantam questões em várias áreas de pesquisa,
porém seus benefícios vão além de uma simples plataforma para execução de
aplicações em larga escala. A idéia é facilitar a colaboração de grupos de
pesquisa distribuídos geograficamente.

Mostramos então que os Grids Computacionais como uma tecnologia que nasceu na
comunidade de alto desempenho e ganhou espaço na indústria através da
transformação da computação distribuída pelo uso de serviços sob demanda. Assim,
a convergência de tecnologias que culminou com a definição do conceito de {\em
  Grid Service} foi um processo natural de evolução dos Grids.

Tendo em vista a nova perspectiva que os {\em Grid Services} trouxeram para o
desenvolvimento dos Grids, a tendência é que Grids se tornem uma
infraestrutura global de computação orientada a serviços, atendendo tanto a
comunidade de computação científica de alto desempenho, quanto a comunidade de
computação comercial.

Finalmente, a discussão sobre os padrões emergentes para o desenvolvimento de
infraestruturas de Grids Computacionais, mostra que os esforços têm amadurecido,
fomentado a pesquisa e o desenvolvimento de ferramentas, que contribuem para a
con\-cre\-ti\-zação de um ambiente amplamente distribuído onde será possível
consumir serviços computacionais de forma transparente.

% \bibliographystyle{ieeetr}
% \bibliography{grid}
% 
% \end{document}



