Baixe o app para aproveitar ainda mais
Prévia do material em texto
SISTEMAS DISTRIBUÍDOS SISTEMAS DISTRIBUÍDOS Copyright © UVA 2021 Nenhuma parte desta publicação pode ser reproduzida por qualquer meio sem a prévia autorização desta instituição. Texto de acordo com as normas do Novo Acordo Ortográfico da Língua Portuguesa. AUTORIA DO CONTEÚDO Thiago Alberto Ramos Gabriel REVISÃO Janaina Vieira Lydianna Lima PROJETO GRÁFICO UVA DIAGRAMAÇÃO UVA SUMÁRIO Apresentação Autor 6 7 8 • Modelos de arquiteturas • Estilos arquitetônicos • Arquiteturas de sistemas e middleware Arquiteturas UNIDADE 1 Comunicação entre processos 40 • Problemas de ligação em rede para sistemas distribuídos • Representação externa de dados e empacotamento • Chamada de procedimento remoto, invocação a método remoto e comunicação orientada às mensagens UNIDADE 2 SUMÁRIO Sincronização 101 • Sincronização de relógios físicos e relógios lógicos • Exclusão mútua • Algoritmos de eleição UNIDADE 4 72 • Nomeação simples • Nomeação estruturada • Nomeação baseada em atributo Nomeação UNIDADE 3 6 A vida no século XXI tem uma dependência crescente de serviços em rede que mudam a estrutura da sociedade. Por exemplo, pesquisa na web, videoconferência, negociação de ações e serviços bancários pela internet, até manter contato com amigos por meio de vários tipos de redes sociais. De certa forma, podemos dizer que os serviços baseados em rede desempenham um papel dominante. As redes fornecem conectividade básica e variados serviços construídos sobre elas são exemplos de sistemas distribuídos. Leslie Lamport observou certa vez: “Um sistema dis- tribuído é aquele em que a falha de um computador que você nem sabia que existia pode tornar seu próprio computador inutilizável.” Embora certamente não seja uma definição, ela caracteriza os desafios de se chegar a uma explicação apropriada de um sistema distribuído. O que é distribuído em um sistema distribuído? Se o processador do sistema de com- putador está localizado a 100 metros de sua memória principal, ele é um sistema dis- tribuído? E se os dispositivos de entrada e saída estiverem localizados a três milhas de distância do processador? Se a distribuição física for levada em consideração, a definição de um sistema distribuído torna-se desconfortavelmente dependente do grau de distribuição física dos componen- tes de hardware, o que certamente não é aceitável. Para aliviar esse problema, é comum caracterizar um sistema distribuído usando-se a distribuição lógica ou funcional de suas capacidades de processamento. Definimos um sistema distribuído como aquele em que os componentes de hardware ou software localizados em computadores em rede se comunicam e coordenam suas ações apenas transmitindo mensagens. Essa definição simples cobre toda a gama de sistemas pelos quais os computadores em rede podem ser implantados de maneira útil. Você irá aprimorar os sistemas de informação, adequando-os em diferentes domínios de aplicação, além de analisar, planejar, especificar e integrar os diferentes elementos e variá- veis para obtenção de soluções criativas e inovadoras aplicadas a diferentes problemas. APRESENTAÇÃO 7 THIAGO ALBERTO RAMOS GABRIEL Graduado em Engenharia de Controle e Automação pelo Instituto de Estudos Superiores da Amazônia – IESAm-PA, com mestrado em Engenharia Mecânica pelo Instituto Militar de Engenharia – IME-RJ, é um apaixonado por novas tecnologias e inovação. Professor da graduação, possui mais de 10 anos de experiência em sistemas distribuí- dos, robótica, automação e visão computacional. Coordenador do curso de Operação com o uso de Drones, com implementações, atendendo às necessidades do dia a dia da sociedade; coordenador de curso técnico em Mecatrônica no Rio de Janeiro. AUTOR Arquiteturas UNIDADE 1 9 Um modelo arquitetônico de um sistema distribuído preocupa-se com o posicionamento de suas partes e os relacionamentos entre elas. Os exemplos incluem o modelo clien- te-servidor e o modelo ponto a ponto. O que torna essas arquiteturas de software im- portantes para sistemas distribuídos é que todas visam alcançar (em um nível razoável) transparência de distribuição. Nesta unidade você terá o conhecimento de estrutura em camadas de software, além de ter a possibilidade de especificar os problemas de design, dificuldades e ameaças que devem ser resolvidos a fim de desenvolver sistemas distribuídos que cumpram suas tarefas de forma correta, confiável e segura. INTRODUÇÃO Nesta unidade você será capaz de: • Identificar como as partes de um sistema distribuído são organizadas para for- mar um sistema único. OBJETIVO 10 Modelos de arquiteturas A arquitetura de um sistema é sua estrutura em termos de componentes específicos, separadamente. O objetivo é garantir que a estrutura atenderá às demandas presentes e futu- ras. As principais preocupações são tornar o sistema confiável, gerenciável, adaptável e econômico. O projeto arquitetônico de um edifício tem aspectos semelhantes, determinando não ape- nas sua aparência, mas também sua estrutura geral e estilo arquitetônico (gótico, neo- clássico, moderno), além de fornecer um quadro de referência consistente para o projeto. Nos últimos anos, os sistemas distribuídos ganharam importância substancial. As ra- zões de sua crescente importância são múltiplas. Vejamos alguns delas: • Primeiro fator - O ambiente distribuído geograficamente: em muitas situações, o próprio ambiente de computação é distribuído geograficamente. Como exemplo, considere uma rede bancária. Cada banco deve manter as contas de seus clientes. Além disso, os bancos comunicam-se entre si para monitorar transações interban- cárias ou registrar transferências de fundos de caixas eletrônicos (ATMs) geografi- camente dispersos. Outro exemplo comum de ambiente de computação distribuído geograficamente é a internet, que influenciou profundamente nosso modo de vida. A mobilidade dos usuários acrescentou uma nova dimensão à distribuição geográfica. • Segundo fator - Acelerar: há a necessidade de acelerar a computação. A veloci- dade de computação em uniprocessadores tradicionais está se aproximando rapi- damente do limite físico. Embora os processadores de vários núcleos, superescala- res e de palavras de instrução muito grandes (VLIW) ampliem o limite, introduzindo o paralelismo no nível de arquitetura, as técnicas não são escaladas muito além de um determinado nível. Uma técnica alternativa para obter mais poder computacional é usar vários processadores. Dividir um problema total em subproblemas menores e atribuir esses subproblemas a processadores físicos separados que podem operar simultaneamente é um método potencialmente atraente para aumentar a velocida- de da computação. Além disso, essa abordagem promove melhor escalabilidade, em que os usuários ou administradores podem aumentar incrementalmente o po- 11 der computacional a partir da compra de elementos de processamento ou recursos adicionais. Este conceito é amplamente utilizado pelos sites de redes sociais para upload e download simultâneos de fotos e vídeos de milhões de clientes. • Terceiro fator - Compartilhamento de recursos: há necessidade de comparti- lhamento de recursos. Aqui, o termo “recurso” representa recursos de hardware e software. O usuário do computador A pode querer usar uma impressora a laser so- fisticada conectada ao computador B, ou o usuário do computador B pode precisar de algum espaço extra em disco disponível com o computador C para armazenar um arquivo grande. Em uma rede de estações de trabalho, a estação de trabalho A pode querer usar os recursos de computação ociosos das estações de trabalho B e C para aumentar a velocidade de uma computação específica. Por meio do Google Docs, o Google permite que você compartilhe seu software para processamento de texto, aplicativo de planilha e criação de apresentação sem nada mais em sua máquina. A computação em nuvem terceiriza essencialmente a infraestrutura de computação deum usuário ou organização para centros de dados. Esses centros permitem que milhares de seus clientes compartilhem seus recursos de computa- ção através da internet para uma computação eficiente e a um custo acessível. • Quarto fator - Tolerância a falhas: poderosos uniprocessadores ou sistemas de computação construídos em torno de um único nó central estão sujeitos a colapso completo quando o processador falha. Muitos usuários consideram isso arriscado. Os sistemas distribuídos têm o potencial de remediar tal problema usando técnicas de tolerância a falhas apropriadas — quando uma fração dos processadores falha, os processos restantes assumem as tarefas dos processadores com falha e mantêm o aplicativo em execução. Por exemplo, em um sistema com redundância modular tripla (TMR), três unidades funcionais idênticas são usadas para realizar o mesmo cálculo e o resultado correto é determinado por uma votação majoritária. Em muitos sistemas distribuídos com tolerância a falhas, os processadores verificam rotineira- mente uns aos outros em intervalos predefinidos, permitindo a detecção automá- tica de falhas, diagnóstico e eventual recuperação. Alguns usuários de aplicativos não críticos estão dispostos a se comprometer com uma degradação parcial no desempenho do sistema quando uma falha prejudica uma fração dos elementos de processamento ou os links de comunicação de um sistema distribuído. Esta é a essência da degradação elegante. Um sistema distribuído, portanto, oferece uma excelente oportunidade para incorporar tolerância a falhas e degradação normal. Existem vários exemplos de sistemas distribuídos que são usados na vida cotidiana em uma variedade de aplicações. Uma fração desses serviços consome muitos dados e o 12 componente computacional é muito pequeno. Os exemplos são aplicativos orientados a banco de dados (pense no Google pesquisando e coletando informações de computado- res em todo o mundo). Outros requerem computação intensiva. A maioria dos sistemas são estruturados como sistemas cliente-servidor, em que a máquina servidora é a cus- tódia dos dados ou recursos e fornece serviço a vários clientes distribuídos geografica- mente. Alguns aplicativos, no entanto, não dependem de um servidor central, pois são sistemas ponto a ponto (P2P). Vejamos, a seguir, alguns exemplos de sistemas distribuídos: • World Wide Web: a World Wide Web (WWW) é um serviço popular executado na in- ternet. Ele permite que os documentos em um computador se refiram a informações textuais ou não textuais armazenadas em outros computadores. Por exemplo, um documento nos Estados Unidos pode conter referências à fotografia de uma floresta tropical na África ou a uma gravação de música na Austrália. Essas referências são destacadas no monitor do usuário e, quando selecionadas por ele, o sistema busca o item de um servidor remoto usando protocolos apropriados e exibe a imagem ou reproduz a música na máquina cliente. A internet e a WWW mudaram a forma como realizamos nossas atividades diárias ou conduzimos nossos negócios. Por exemplo, uma grande fração das reservas de passagens aéreas e hotéis agora são feitas pela internet. As compras pela internet aumentaram dramaticamente nos últimos anos. Milhões de pessoas agora negociam ações rotineiramente pela rede. Os amantes de música baixam e trocam músicas com qualidade de CD, levando as compras antigas de CDs e DVDs à quase obsolescência. Bibliotecas digitais fornecem aos usuários acesso instantâneo a informações de arquivo no conforto de suas casas. • Redes sociais: a interação social mediada pela internet testemunhou um cresci- mento dramático nos últimos tempos. Milhões de usuários agora usam seus com- putadores desktop, laptop ou smartphones para postar e trocar mensagens, fotos e videoclipes com seus amigos usando esses sites de relacionamento. Membros de redes sociais podem se socializar lendo as páginas de perfil de outros membros e entrando em contato com eles. As interações entre os sócios geralmente levam à formação de comunidades virtuais ou clubes que compartilham interesses co- muns. As entradas dos membros são gerenciadas por milhares de servidores em uma ou mais localizações geográficas e esses servidores realizam tarefas especí- ficas em nome dos membros. Alguns lidam com fotos, outros lidam com vídeos ou com mudanças de membros etc. Conforme o número de membros aumenta, mais servidores são adicionados ao pool e servidores poderosos substituem os mais lentos. 13 • Redes interbancárias: Amy precisa de US $ 300 em uma manhã de domingo, então ela vai até um caixa eletrônico próximo para sacar o dinheiro. Amy tem uma conta-corrente em Iowa City, mas ela tem duas contas de poupança: uma em Chi- cago e outra em Denver. Cada banco estabeleceu um limite máximo de $ 100 para o saque diário de dinheiro, então Amy usa três cartões bancários diferentes para sacar o valor desejado. Esses débitos são imediatamente registrados em suas con- tas bancárias em três cidades diferentes e seus novos saldos são recalculados. Os caixas eletrônicos estão cadastrados nas respectivas instituições financeiras, sendo que a rede interbancária realiza toda a operação. • Redes ponto a ponto: os sistemas P2P são bastante populares para compartilha- mento de arquivos, distribuição de conteúdo e telefonia pela internet. Historicamen- te, o Napster foi o pioneiro no uso da tecnologia P2P para compartilhar as coleções pessoais de músicas de seus clientes. Em vez de armazenar as músicas em um computador central, elas vivem nas máquinas dos usuários. Existem milhões delas espalhados por todo o mundo. Quando você deseja baixar uma música usando o Napster, você está baixando da máquina de outra pessoa, e essa pessoa pode ser do seu vizinho ou de alguém do outro lado do mundo. Isso levou ao desenvolvimen- to de compartilhamento de dados P2P. O Napster não era um verdadeiro sistema P2P, pois usava um diretório centralizado. Porém, muitos sistemas subsequentes que fornecem serviço semelhante (por exemplo, Gnutella, KaZaA) evitaram o uso de um servidor central ou de um diretório central. Agora, os sistemas P2P encontram aplicativos em áreas além da troca de arquivos de música. Por exemplo, o projeto OceanStore da University of California, Berkeley, construiu um mecanismo de arqui- vamento de dados on-line em cima de uma rede P2P subjacente Tapestry. Milhões de pessoas usam o Skype desenvolvido em torno da tecnologia P2P para telefonia pela internet e chats de vídeo. • Sistemas distribuídos em tempo real: os sistemas distribuídos em tempo real lidam com a coordenação crítica de eventos em um ambiente distribuído geografi- camente. As plantas industriais usam extensivamente redes de controladores para supervisionar a produção e a manutenção. Considere uma fábrica de produtos quí- micos, na qual um controlador mantém a pressão de uma certa câmara a 200 psi. À medida que a pressão do vapor aumenta, a temperatura tende a aumentar. Portanto, há outro controlador a 300 pés de distância que controla o fluxo de um refrigerante. Esse refrigerante garante que a temperatura da câmara nunca ultrapasse 83 °C. Além disso, a segurança da planta exige que o produto da pressão e da temperatura não exceda 35.000. Aqui, o sistema de computação distribuída mantém uma relação de invariância nos parâmetros do sistema monitorados e controlados por controla- 14 dores independentes. Em redes de controle de tráfego urbano, os computadores nos diferentes pontos de controle controlam os sinais de tráfego para minimizar o congestionamento e maximizar o fluxo. As redes veiculares permitem a comunica- ção espontânea entre veículos sem fio, o que não só permite que os veículos com- partilhem informações sobre as condições das estradas com outros veículos, mas também abre a possibilidade de melhorar a mobilidade e a segurança coletivas. • Redes de sensores: o custo decrescente do hardware e o crescimento da tecno- logia sem fio geraram novas oportunidadesno projeto de sistemas distribuídos para aplicações específicas ou para fins especiais. Uma dessas aplicações é uma rede de sensores. Cada nó é um processador em miniatura equipado com alguns sen- sores que detectam vários parâmetros ambientais e é capaz de comunicação sem fio com outros nós. Essas redes podem ser potencialmente usadas em uma ampla classe de problemas, indo desde vigilância em campos de batalha, detecção de ata- ques químicos e biológicos, até saúde, automação residencial, ecológica e monito- ramento de habitat. Isso é parte de uma visão mais ampla da computação ubíqua. • Grid e computação em nuvem: Grid computing é uma forma de computação distribuída que oferece suporte à programação paralela em uma rede de compu- tadores. Na extremidade inferior, uma grade computacional pode usar uma fração dos recursos computacionais de uma ou duas organizações, enquanto na extremi- dade superior ela pode combinar milhões de computadores em todo o mundo para trabalhar em projetos computacionais extremamente grandes. O objetivo é resolver problemas computacionais difíceis de maneira mais rápida e econômica do que por métodos convencionais. Aqui, fornecemos dois exemplos. Veja: 1. Primeiro exemplo é o Large Hadron Collider – LHC: acelerador de partí- culas e um complexo de teste experimental construído na Organização Eu- ropeia de Pesquisa Nuclear (CERN), que começou a operar em 2008 e está sendo usado para responder a questões fundamentais da ciência. Os expe- rimentos científicos geram aproximadamente 15 PB de dados a cada ano (1 PB = 1015 bytes, e isso é o equivalente a mais de 20 milhões de CDs). Esses dados são distribuídos ao redor do globo para 11 grandes centros de computação localizados no Canadá, França, Alemanha, Itália, Holanda, paí- ses nórdicos, Espanha, Taipei, Reino Unido e dois locais nos Estados Unidos, formando uma organização virtual mundial. Esses centros Tier-1 disponibili- zam os dados para mais de 150 centros Tier-2 para tarefas de análise espe- cíficas. Cientistas em vários países podem acessar localmente os dados do LHC usando computadores e computadores locais. 15 2. Segundo exemplo é o projeto SETI @ home. Existem extraterrestres? SETI (sigla para search for extraterrestrial intelligence) é um grande projeto que visa descobrir a existência de vida extraterrestre no universo. O grande volume de dados que está sendo constantemente coletado de centenas de radiotelescópios precisa ser analisado para se chegar a qualquer conclusão sobre a possível existência de vida extraterrestre. Isso requer um grande po- der de computação. Em vez de usar supercomputadores, a equipe do SETI da Universidade da Califórnia, em Berkeley, decidiu aproveitar o poder de computação ocioso de milhões de PCs e estações de trabalho pertencentes a você e a mim, poder de computação que de outra forma seria desperdiçado executando programas de proteção de tela inúteis. Atualmente, cerca de 40 GB de dados são puxados diariamente pelo telescópio e enviados a mais de três milhões de computadores em todo o mundo para serem analisados. Os resultados são enviados de volta pela internet, e o programa então coleta um novo segmento de sinais de rádio para o PC trabalhar. O sistema executa 14 trilhões de operações de ponto flutuante por segundo e acumulou mais de 500.000 anos de uso do PC no último ano e meio. Normalmente, custaria milhões de dólares para se conseguir esse tipo de energia em um ou mesmo dois supercomputadores. A computação em nuvem permite que os clientes terceirizem seu uso de software, ar- mazenamento de dados e até mesmo a infraestrutura de computação para data centers remotos. Os clientes interagem com o armazenamento em nuvem e aplicativos por meio da internet usando seus navegadores da web. Os usuários não precisam adquirir ou man- ter hardware e software caros, mas, mesmo assim, realizam suas tarefas pagando pelo uso dos recursos. Com a ampla disponibilidade de redes de alta velocidade e o custo decrescente dos computadores, a computação em nuvem oferece uma alternativa eco- nômica à computação convencional. Ela apresenta uma abordagem flexível em que os usuários podem aumentar sua capacidade de computação rapidamente como um ser- viço pay-per-use. A tarefa de manter hardware e software nos centros de dados é do pro- vedor de serviços em nuvem, responsável por supervisionar o compartilhamento perfeito desses recursos e manter a privacidade dos dados do usuário. A divisão de responsabilidades entre os componentes do sistema (aplicativos, servido- res e outros processos) e a colocação dos componentes nos computadores da rede é talvez o aspecto mais evidente do projeto de sistema distribuído. Isso tem implicações importantes para o desempenho, confiabilidade e segurança do sistema resultante. Nes- te tópico, delineamos os principais modelos arquitetônicos nos quais se baseia essa dis- tribuição de responsabilidades. 16 Em um sistema distribuído, os processos com responsabilidades bem definidas intera- gem entre si para desempenhar uma atividade útil. Neste tópico, nossa atenção se con- centrará no posicionamento dos processos, ilustrado na forma da figura que apresen- taremos a seguir, mostrando a disposição dos processos (elipses) nos computadores (caixas azuis claras). Utilizamos os termos “invocação” e “resultado” para rotular mensa- gens, mas eles também podem ser rotulados como “solicitação” e “resposta”. Clientes chamam servidores individuais. Fonte: Elaborada pelo autor (2021). Cliente-servidor: essa é a arquitetura mais frequentemente citada quando os sistemas distribuídos são discutidos. Historicamente, é o mais importante e continua a ser o mais utilizado. A figura adiante ilustra a estrutura simples na qual os processos do cliente inte- ragem com os processos de servidor individuais em computadores host separados para acessar os recursos compartilhados que eles gerenciam. Os servidores podem, por sua vez, ser clientes de outros servidores, como indica a figura. Por exemplo, um servidor da web geralmente é um cliente de um servidor de arquivos local que gerencia os arquivos nos quais as páginas da web são armazenadas. Os ser- vidores da web e a maioria dos outros serviços da internet são clientes do serviço DNS, que traduz os nomes de domínio da internet em endereços de rede. Outro exemplo re- lacionado à web diz respeito aos mecanismos de pesquisa, que permitem aos usuários consultar resumos de informações disponíveis em páginas da web em sites da internet. Envio Envio Resultado Result ado Processo PC Cliente Cliente Servidor Servidor 17 Esses resumos são feitos por programas chamados de rastreadores da web, que ficam em segundo plano em um site de mecanismo de pesquisa usando solicitações HTTP para acessar servidores da web na internet. Assim, um mecanismo de pesquisa é um servidor e um cliente: ele responde a consultas de clientes de navegadores e executa rastreadores da web que atuam como clientes de outros servidores. Neste exemplo, as tarefas do servidor (responder às consultas do usuário) e as tarefas do rastreador (fa- zer solicitações a outros servidores da web) são totalmente independentes; há pouca necessidade de sincronizá-los e elas podem ser executados corretamente. Na verdade, um mecanismo de pesquisa típico normalmente incluiria muitos threads simultâneos de execução, alguns servindo a seus clientes e outros executando rastreadores da web. Arquitetura ponto a ponto. Fonte: Elaborada pelo autor (2021). Ponto a ponto: nessa arquitetura, todos os processos envolvidos em uma tarefa ou ati- vidade desempenham papéis semelhantes, interagindo cooperativamente como pares, sem qualquer distinção entre processos cliente e servidor ou os computadores aos quais eles se conectam. Embora o modelo cliente-servidor ofereça uma abordagem direta e relativamente simples para o compartilhamento de dados e outros recursos, ele é mal dimensionado. A centralização da provisão e gerenciamento deserviços implícita na co- locação de um serviço em um único endereço não vai muito além da capacidade do computador que hospeda o serviço e da largura de banda de suas conexões de rede. Ponto 1 Ponto 4 Objetos Compartilháveis ..... Ponto N Ponto 2 Ponto 3 App App App 18 A capacidade do hardware e a funcionalidade do sistema operacional dos computadores desktop de hoje excedem a dos servidores de ontem e a maioria está equipada com co- nexões de rede de banda largas sempre ativas. O objetivo da arquitetura ponto a ponto é explorar os recursos (tanto dados quanto de hardware) em um grande número de compu- tadores participantes para o preenchimento de uma dada tarefa ou atividade. Aplicativos e sistemas ponto a ponto foram construídos com sucesso, permitindo que dezenas ou centenas de milhares de computadores forneçam acesso a dados e outros recursos que eles armazenam e gerenciam coletivamente. A instância mais antiga e mais conhecida é o aplicativo Napster para compartilhamento de arquivos de música digital. Embora tenha se tornado famoso por outras razões além de sua arquitetura, sua demonstração de viabi- lidade resultou no desenvolvimento do modelo arquitetônico em muitas direções valiosas. Na figura Arquitetura ponto a ponto, mostrada anteriormente, o formato de um aplicativo ponto a ponto, em que estes são compostos por diversos números de processos pares rodando em computadores individuais e o padrão de comunicação entre eles, se torna inteiramente dependente dos requisitos do aplicativo. No que diz respeito também aos objetos de dados, um número considerável é compartilhado. Um computador individual contém uma parcela pequena do banco de dados do aplicativo e as cargas de armaze- namento, comunicação e processamento para acesso aos objetos são distribuídas por muitos computadores e links de rede. Assim, há a replicação de cada objeto em diversos computadores para distribuir ainda mais a carga e fornecer resiliência em caso de desco- nexão de computadores individuais (como é inevitável nas grandes redes heterogêneas às quais os sistemas ponto a ponto são direcionados). A necessidade de colocar objetos individuais e recuperá-los e de manter réplicas entre vários computadores faz com que essa arquitetura seja substancialmente mais complexa em comparação à arquitetura cliente-servidor. Portanto, percebemos que os modelos de arquiteturas existem em sistemas distribuídos. Ao se falar em sistemas distribuídos é impossível não discutir acerca dos modelos de arquiteturas desses sistemas, que possuem diversos tipos de arquitetura conforme a necessidade do projeto. 19 Estilos arquitetônicos Iniciaremos levando em consideração a organização lógica de sistemas distribuídos em componentes de software, também conhecida como arquitetura de software. No decor- rer do tempo, pesquisas relacionadas às arquiteturas de software tiveram sua importân- cia e progresso, quando já é notório e aceitável que em projetos são de extrema neces- sidade para uma arquitetura, tendo seu êxito no desenvolvimento de grandes sistemas. A organização de sistemas distribuídos cuida, em sua maioria, dos componentes de soft- ware que estabelecem o sistema. Essa arquitetura de software fala a respeito de que forma diversos componentes são organizados e como vão interagir entre eles. Um estilo arquitetônico é organizado em termos de componentes, de tal forma que este- jam conectados entre si — a forma de troca de dados entre os componentes e a forma como esses elementos são configurados em conjunto para a formação de um sistema. Componente é uma unidade modular com interfaces requeridas e fornecidas bem definidas, que é substituível dentro de seu ambiente (OMG, 2004b). Conector é descrito como o mecanismo que serve de mediador da comu- nicação ou da cooperação entre componentes (MEHTA, et al., 2000; SHAW; CLEMENTS, 1997). Podemos exemplificar um conector como sendo formado pela disposição para chamadas de procedimentos (remotas), transmissão de mensagens ou fluxo de dados. Com o uso de componentes e conectores é possível descrever as cadeias de conexão dos estilos arquitetônicos, em seus inúmeros sistemas de aplicações distribuídas por en- tre configurações diversas alternadas e com comunicação por interfaces. Entre os vários estilos, podemos destacar os seguintes: Arquitetura em camadas. Arquiteturas baseadas em objetos. Arquiteturas centradas em dados. Arquiteturas baseadas em eventos. 20 Em arquitetura em camadas, seus componentes são organizados em camadas, em que cada componente da camada Li pode chamar um componente da camada Li-1, porém Li-1 não pode chamar a camada Li. Este é um modelo extensamente adotado pela comunidade de redes, em que seu controle flui de camada para camada tendo suas requisições descendo pela hierarquia e seus resultados fluindo para cima, como mostra a figura a seguir. Organizações em camadas. Fonte: Elaborada pelo autor (2021). A finalidade de camadas é familiar e há uma relação bem estreita ao esquecimento. Quando observamos um desempenho em camadas, um sistema robusto é particionado em diversas delas, tendo uma determinada camada fazendo uso dos serviços oferecidos pela camada abaixo. Referenciar uma certa camada, portanto, oferece uma abstração de software, com as camadas em nível mais alto não sabendo os detalhes de implementa- ção ou, todavia, quaisquer outras camadas abaixo delas. Em termos de sistemas distribuídos, isso equivale a uma organização vertical de ser- viços em camadas de serviço. Um serviço distribuído pode ser fornecido por um ou mais processos do servidor, interagindo entre si e com os processos do cliente, a fim de manter uma visão consistente de todo o sistema dos recursos do serviço. Por exemplo, Camada N Camada N – 1 Camada 2 Camada 1 Camada N – 1 Camada N – 3 Camada N – 2 Camada N – 1 Camada N – 2 Camada N Camada N Pedido/Resposta Handle Upcall Chamada unilateral 21 um serviço de horário de rede é implementado na internet com base no Network Time Protocol – NTP por processos de servidor em execução em hosts em toda a internet, que fornecem a hora atual a qualquer cliente que a solicita e ajusta sua versão da hora atual como resultado de interações entre si. Dada a complexidade dos sistemas distribuídos, geralmente é útil organizar esses serviços em camadas. Apresentamos uma visão co- mum dessa arquitetura na figura a seguir. Camadas de serviço de software e hardware em sistemas distribuídos. Fonte: Elaborada pelo autor (2021). A figura Camadas de serviço de software e hardware em sistemas distribuídos apre- senta os termos importantes, plataforma e middleware, que definimos da seguinte forma: • Uma plataforma para sistemas e aplicativos distribuídos consiste nas camadas de hardware e software de nível mais baixo. Essas camadas de baixo nível fornecem serviços para as camadas acima delas, que são implementadas de forma indepen- dente em cada computador, elevando a interface de programação do sistema a um nível que facilita a comunicação e a coordenação entre os processos. Intel x86/ Windows, Intel x86/Solaris, Intel x86/Mac OS X, Intel x86/Linux e ARM/Symbian são os principais exemplos. • Middleware foi conceituado como uma camada de software a fim de mascarar a diferença e oferecer um modelo de programação conveniente aos programadores Aplicativos, serviços Plataforma Middleware Hardware de rede e computador Sistema operacional 22 de aplicativos. Middleware é representado por processos ou objetos em um con- junto de computadores que interagem entre si para implementar comunicação e suporte de compartilhamento de recursos para aplicativos distribuídos. Ele se preo- cupa em fornecer blocos de construção úteis para a construção de componentes de software que podem funcionar uns com os outros em um sistema distribuído. Em particular, ele aumenta o nível das atividades de comunicação de programas de aplicativos por meio do suporte de abstrações,como a chamada de método remoto, comunicação entre um grupo de processos, notificação de eventos, particionamen- to, colocação e recuperação de objetos de dados compartilhados entre computado- res cooperantes, replicação de objetos de dados compartilhados e transmissão de dados multimídia em tempo real. Em arquitetura baseada em objetos e orientadas a serviços, os objetos correspondem às definições de componentes. São conectados por meio de chamada de procedimento (remota) e é um tipo de organização mais solta. São utilizados padrões do modelo de conexão cliente-servidor e também de programação dispersada (CORBA, RMI etc.). Arquitetura baseada em objetos. Fonte: Tanebaum (2021). Chamada de método Objeto Objeto Objeto Objeto Objeto 23 Para sistemas de software de grande porte, as arquiteturas em camadas e baseadas em objetos são os estilos mais importantes. As Arquiteturas Centradas em Dados têm sua evolução com base na ideia de que pro- cessos se comuniquem a partir de repositório comum, seja passivo ou ativo. Como argu- mento tem-se, em sistemas distribuídos, que essas arquiteturas são muito importantes em comparação às arquiteturas em camadas ou baseadas em objetos. Podemos pensar no desenvolvimento de uma exuberância de aplicações em rede que resultam de um sis- tema distribuído de arquivos compartilhados no qual praticamente toda a comunicação ocorre por meio de arquivos. Arquitetura centrada em dados. Fonte: Tanebaum (2021). Em Arquiteturas baseadas em eventos, processos se comunicam, em suma, por meio da propagação de eventos que, voluntariamente, também transportam dados, conforme mostra a figura seguir. No caso de sistemas distribuídos, a propagação de eventos tem sido associada, de forma geral, com o que denominamos sistemas publicar/subscrever. A principal finalidade é que processos publiquem eventos após os quais o middleware assegura que somente os processos que se subscrevem para esses eventos os rece- berão. O principal interesse de sistemas baseados em eventos é que os processos são fracamente acoplados. Entrega de dados Publicar Espaço de dados (persistente) compartilhado Componente Componente 24 Arquiteturas baseadas em eventos. Fonte: Tanebaum (2021). Após estudar um pouco sobre os estilos arquitetônicos, abordaremos de forma breve como eles são organizados, considerando onde são colocados os componentes de software, sua interação e sua colocação. As principais arquiteturas de sistemas são: • Arquiteturas centralizadas. • Arquiteturas descentralizadas. • Arquiteturas híbridas. Arquiteturas centralizadas Em um modelo cliente-servidor básico processos em um sistema distribuído são divi- didos em dois grandes grupos: • Servidor: um processo que implementa um serviço específico. • Cliente: um processo que requisita um serviço de um servidor enviando uma re- quisição e, posteriormente, esperando pela resposta do servidor, conforme mostra a figura a seguir. Entrega de evento Publicar Componente Componente Componente Barramento de eventos 25 Cliente x Servidor. Fonte: Tanebaum (2021). Por meio de um protocolo é possível implementar a comunicação entre um cliente e um servidor, sem conexão, típico do que acontece em redes locais, desde que o ambiente seja confiável. Logo, quando um serviço é requisitado por um cliente tem-se um empa- cotamento da mensagem para o servidor, verificando-se o serviço que se deseja, junto com os dados de entrada necessários. Por fim, a mensagem é enviada ao servidor, que sempre irá aguardar pela chegada da requisição para que, na sequência, processe e em- pacote os resultados em uma mensagem de resposta que é enviada ao cliente. Arquiteturas descentralizadas Esses tipos de arquiteturas são uma consequência direta da divisão de aplicações em uma interface de usuário em componentes de processamento e em um nível de da- dos. As divisões distintas referem-se diretamente à organização lógica das aplicações. Nos mais diversos ambientes de negócios, processamento distribuído corresponde a organizar uma aplicação cliente-servidor como uma arquitetura descentralizada, conhe- cida também como distribuição vertical. Essa distribuição vertical é obtida colocando-se componentes, de forma lógica, em diferentes máquinas. O termo parte do conceito de fragmentação vertical, como a utilizada em bancos de dados relacionais distribuídos, em que se observa que as tabelas são subdivididas em colunas e, posteriormente, distribuí- das por diversas máquinas. Espera resultado Fornece serviço Resposta Cliente Requisição Servidor Tempo 26 Servidor que age como um cliente. Fonte: Tanebaum (2021). Arquiteturas híbridas Em uma arquitetura híbrida, uma de suas classes importantes são os sistemas de ser- vidor de borda, que se tem disponibilizado na internet, no qual servidores são colocados “na borda” da rede. Esse tipo de borda é composto pela fronteira entre as redes corpora- tivas e a internet de fato, sendo fornecida por um provedor de serviço de internet – ISP. De forma semelhante, quando usuários finais que estão em suas casas se conectam com a internet através do ISP, pode-se considerar que o ISP reside na borda da internet, conforme vemos na figura adiante. Visão da internet como rede composta por um conjunto de servidores de borda. Fonte: Tanebaum (2021). Interface de usuário (apresentação) Operação de requisição Requisitar dados Retornar dados Retornar resultado Esperar resultado Esperar dados Servidor de aplicação Tempo Servidor de banco de dados Servidor de borda Rede corporativa Provedor de conteúdoCliente ISP ISP 27 Outro tipo de sistema é Sistemas Distribuídos Colaborativos, em que os sistemas dis- tribuídos são disponibilizados. O ponto principal nesse tipo de sistema é engrenar, dar a partida inicial para que seja disponibilizado um esquema cliente-servidor tradicional. Para melhor exemplificar, consideremos um sistema de compartilhamento de arquivos BitTorrent, que é um sistema peer-to-peer de transferência de arquivos, como mostra a figura a seguir. Sua principal finalidade básica é de um usuário que, ao buscar um arquivo, ele transfi- ra porções do arquivo de outros usuários até que as porções transferidas possam ser montadas em conjunto, resultando no arquivo completo. Para que se tenha um arquivo, o usuário precisa acessar um diretório global, que é apenas um de alguns sites web bem conhecidos. Tal diretório contém referências ao que denominamos arquivos .torrent. Funcionamento principal do BitTorrent. Fonte: Tanebaum (2021). É importante registrar que é crucial adotar uma arquitetura de software para um projeto. A composição do sistema distribuído tem como base o estilo arquitetônico, com formula- ção baseada nos componentes que o envolvem, tendo sua maneira de conexão de seus respectivos componentes e a forma de configuração do conjunto dos elementos. Nó cliente Lockup (F) SERVIDOR WEB Ref. a servidor de arquivo Uma página Web BitTorrente Arquivo .torrent para F Ref. a rastreadorSERVIDOR DE ARQUIVO RASTREADOR K de N nós Nó 1 Nó 2 Nó 3 Lista de nós que armazenam F 28 Arquiteturas de sistemas e middleware O termo middleware aplica-se a uma camada de software que fornece uma abstração de programação, bem como mascara a heterogeneidade das redes, hardware, sistemas operacionais e linguagens de programação subjacentes. Por exemplo, temos o Common Object Request Broker – CORBA. Alguns middleware, como Java Remote Method Invoca- tion – RMI, suportam apenas uma única linguagem de programação. A maioria do mid- dleware é implementada sobre os protocolos da internet, que mascaram as diferenças das redes subjacentes. Porém, todo middleware lida com as diferenças nos sistemas operacionais e hardware. Além de resolver os problemas de heterogeneidade, o middleware fornece um modelo computacional uniforme para uso por programadores de servidores e aplicativos distribuí- dos. Os modelos possíveis incluem invocação de objetoremoto, notificação de evento re- moto, acesso SQL remoto e processamento de transação distribuída. Por exemplo, o COR- BA fornece invocação remota de objetos, o que permite que um objeto em um programa em execução em um computador invoque um método de um objeto em um programa em execução em outro computador. Sua implementação oculta o fato de que as mensagens são passadas por uma rede para enviar a solicitação de invocação e sua resposta. A tarefa do middleware é fornecer uma abstração de programação de ní- vel superior para o desenvolvimento de sistemas distribuídos e, por meio de camadas, abstrair a heterogeneidade na infraestrutura subjacente para pro- mover interoperabilidade e portabilidade. As soluções de middleware são ba- seadas nos modelos de arquitetura e também oferecem suporte a padrões de arquitetura mais complexos. Categorias de middleware Pacotes de chamada de procedimento remoto, como Sun RPC e sistemas de comunica- ção de grupo, como ISIS, estavam entre as primeiras instâncias de middleware. Desde então, uma ampla gama de estilos de middleware surgiu, com base em grande parte nos modelos arquitetônicos apresentados acima. Apresentaremos uma taxonomia de tais plataformas de middleware por meio de uma tabela, incluindo referências cruzadas a outros capítulos que cobrem as várias categorias 29 com mais detalhes. Deve-se ressaltar que as categorizações não são exatas e que as plataformas de middleware modernas tendem a oferecer soluções híbridas. Por exemplo, muitas plataformas de objetos distribuídos oferecem serviços de eventos distribuídos para complementar o suporte mais tradicional para chamada de método remoto. Da mesma forma, muitas plataformas baseadas em componentes (e de fato outras ca- tegorias de plataforma) também oferecem suporte a interfaces e padrões de serviço da web, por razões de interoperabilidade. Também deve ser enfatizado que essa taxonomia não se destina a ser completa em termos do conjunto de padrões de middleware e tec- nologias disponíveis hoje, mas sim a ser um indicativo das principais classes de middle- ware. Outras soluções (não mostradas) tendem a ser mais específicas, como oferecer paradigmas de comunicação particulares como passagem de mensagens, chamadas de procedimento remoto, memória compartilhada distribuída, espaços de tupla ou comuni- cação em grupo. Categorias de middleware. CATEGORIAS PRINCIPAIS SUBCATEGORIAS SISTEMAS DE EXEMPLO Objetos distribuídos Padrão RM-ODP Plataforma CORBA Plataforma Java RMI Componentes distribuídos Componentes leves Fractal Componentes leves OpenCOM Servidores de aplicativos SUN EJB Servidores de aplicativos Modelo de componente CORBA Servidores de aplicativos JBoss Sistemas publicar/assinar --- Serviço de evento CORBA --- Scribe 30 --- JMS Filas de mensagens --- Websphere MQ --- JMS Serviços web Serviços web Apache Axis Serviços de rede Globus Toolkit Peer–to–peer Sobreposições de roteamento Pastry Sobreposições de roteamento Tapestry Específico do aplicativo Squirrel Específico do aplicativo OceanStore Específico do aplicativo Ivy Específico do aplicativo Gnutella Fonte: Elaborada pelo autor (2021). A categorização de nível superior do middleware, como mostra a tabela anterior, é condu- zida pela escolha de entidades comunicantes e paradigmas de comunicação associados e segue cinco dos principais modelos de arquitetura: • Objetos distribuídos. • Componentes distribuídos. • Sistemas de publicação de assinatura. • Filas de mensagens. • Serviços da web. Eles são complementados por sistemas ponto a ponto, um ramo bastante separado do middleware com base na abordagem cooperativa. A subcategoria de componentes dis- tribuídos mostrados como servidores de aplicativos também fornece suporte direto para arquiteturas de três camadas. Em particular, os servidores de aplicativos fornecem es- 31 trutura para suportar uma separação entre a lógica do aplicativo e o armazenamento de dados, junto com o suporte para outras propriedades, como segurança e confiabilidade. Além de abstrações de programação, o middleware também pode fornecer serviços de sistema distribuído de infraestrutura para uso por programas aplicativos ou outros ser- viços. Esses serviços de infraestrutura são fortemente vinculados ao modelo de progra- mação distribuída que o middleware fornece. Por exemplo, o CORBA fornece aplicativos com uma variedade de seus serviços, incluindo suporte para tornar os aplicativos segu- ros e confiáveis. Os servidores de aplicativos também fornecem suporte intrínseco para tais serviços. Limitações de middleware Muitos aplicativos distribuídos dependem inteiramente dos serviços fornecidos pelo mi- ddleware para suportar suas necessidades de comunicação e compartilhamento de da- dos. Por exemplo, um aplicativo adequado ao modelo cliente-servidor, como um banco de dados de nomes e endereços, pode contar com um middleware que fornece apenas invocação de método remoto. Muito foi alcançado na simplificação da programação de sistemas distribuídos por meio do desenvolvimento de suporte a middleware, mas alguns aspectos da confiabilidade dos sistemas requerem suporte no nível do aplicativo. Considere a transferência de grandes mensagens de correio eletrônico do host de correio do remetente para o do destinatário. À primeira vista, é uma aplicação simples do proto- colo de transmissão de dados TCP. Considere, porém, o problema de um usuário que ten- ta transferir um arquivo muito grande em uma rede potencialmente não confiável. O TCP fornece alguma detecção e correção de erros, mas não pode se recuperar de grandes interrupções de rede. Portanto, o serviço de transferência de correio adiciona outro nível de tolerância a falhas, mantendo um registro do progresso e retomando a transmissão usando uma nova conexão TCP se a original quebrar. Um artigo clássico de Saltzer, Reed e Clarke (SALTZER et al. 1984) faz uma observação semelhante e valiosa sobre o design de sistemas distribuídos, que eles chamam de “o argumento ponta a ponta”. Para parafrasear sua declaração: algumas funções relacionadas à comunicação podem ser implementadas de forma completa e confiável apenas com o conhecimento e a ajuda do aplicativo que está nos pontos finais do sistema de comunicação. Portanto, fornecer 32 essa função como um recurso do próprio sistema de comunicação nem sempre é sen- sato (embora uma versão incompleta da função fornecida pelo sistema de comunicação possa às vezes ser útil como aprimoramento de desempenho). Pode-se ver que seu argumento vai contra a visão de que todas as atividades de comuni- cação podem ser abstraídas da programação de aplicativos pela introdução de camadas de middleware apropriadas. O cerne de seu argumento é que o comportamento correto em programas distribuídos depende de verificações, mecanismos de correção de erros e medidas de segurança em muitos níveis, alguns dos quais requerem acesso aos dados dentro do espaço de ende- reço do aplicativo. Qualquer tentativa de realizar as verificações dentro do sistema de comunicação por si só garantirá apenas parte da correção exigida. Portanto, é provável que o mesmo trabalho seja duplicado em programas aplicativos, desperdiçando esforço de programação e, mais importante, adicionando complexidade desnecessária e cálcu- los redundantes. Não há espaço para detalhar seus argumentos aqui, mas a leitura do artigo citado é altamente recomendável — ele está repleto de exemplos esclarecedores. Um dos autores originais apontou recentemente que os benefícios substanciais que o uso do argumento trouxe para o design da internet são colocados em risco por movimentos recentes em direção à especialização de serviços de rede para atender aos requisitos de aplicativos atuais. Esse argumento representa um dilema real para designers de middleware e, de fato, as difi- culdades estão aumentando devido à ampla gama de aplicativos (e condições ambientais associadas) em sistemas distribuídoscontemporâneos. Em essência, o comportamento correto do middleware subjacente é uma função dos requisitos de um determinado aplica- tivo ou conjunto de aplicativos e do contexto ambiental associado, como o estado e o estilo da rede subjacente. Essa percepção está direcionando o interesse em soluções adaptati- vas e cientes do contexto para middleware, conforme discutido em Kon et al. (2002). O que é necessário para sistemas distribuídos, portanto, é uma infraestrutura que su- porte adequadamente o desenvolvimento e a execução de aplicativos distribuídos. Uma plataforma de middleware apresenta essa infraestrutura porque fornece um buffer entre os aplicativos e a rede. A rede fornece apenas um mecanismo de transporte e o aces- so a ele depende muito de fatores tecnológicos, diferindo entre várias plataformas físi- cas. O middleware pode homogeneizar o acesso às redes e oferece serviços genéricos para aplicativos. Também une domínios tecnológicos e encapsula as diferenças entre diferentes sistemas. 33 O middleware é apresentado sob duas perspectivas diferentes: a da visão dos progra- madores de aplicativos e a da visão dos programadores de sistemas. Os programa- dores de aplicativos consideram o middleware uma ferramenta que os ajuda no desen- volvimento de aplicativos distribuídos. Esses programadores normalmente não estão interessados em como o middleware é implementado, mas apenas em como é usado. Os programadores de aplicativos veem a plataforma de distribuição como uma caixa preta com uma interface bem definida e funcionalidade prescrita. Os programadores de sistemas têm uma visão complementar. Eles consideram a plata- forma de distribuição uma caixa branca e estão interessados principalmente em seus pro- cessos internos. O aplicativo em execução em um middleware é de menor importância. O ponto de referência comum para ambos os tipos de programador é a in- terface para o middleware, que é usado por programadores de aplicativos e fornecido por programadores de sistemas. Nossa abordagem é examinar o middleware de ambos os pontos de vista e usar essas informações como base para aprimorar o conhecimento dos programadores de siste- mas e aplicativos. Os programadores de sistemas são apresentados aos requisitos do lado dos aplicativos para os quais as soluções devem ser produzidas. O conhecimento sobre o funcionamento interno das plataformas de distribuição ajuda os programadores de aplicativos a otimizarem o uso das funções disponíveis. O conceito dos dois pontos de vista percorre o livro como um fio. Nosso objetivo é fornecer uma visão abrangente da arquitetura e do design do middleware. Vamos examinar as tarefas realizadas pelo middleware e limitaremos a discussão ao suporte de middleware de um aplicativo baseado em objeto porque os conceitos de um modelo de objeto refletem idealmente as características dos sistemas distribuídos. Um objeto encapsula o estado e o comportamento e só pode ser acessado por meio de uma interface bem definida. A interface oculta os detalhes específicos da implementação, aju- dando assim a encapsular diferentes tecnologias. Um objeto, portanto, torna-se uma uni- dade de distribuição. Lembre-se de que os objetos se comunicam trocando mensagens. 34 Para o contexto deste material definimos as seguintes tarefas de middleware: Suporte ao modelo de objeto O middleware deve oferecer mecanismos para suportar os conceitos incorporados no modelo de objeto. Interação operacional O middleware deve permitir a interação operacional entre dois objetos. O modelo usado é a invocação de método de uma linguagem de programação orientada a objetos. Interação remota O middleware deve permitir a interação entre dois objetos loca- lizados em diferentes espaços de endereço. Transparência de distribuição Do ponto de vista do programa, a interação entre os objetos é idêntica para interações locais e remotas. Independência tecnológica O middleware suporta a integração de diferentes tecnologias. A estrutura de uma plataforma de middleware Como mencionamos anteriormente, o middleware está conceitualmente localizado entre o aplicativo e o sistema operacional, como mostra a figura a seguir. Como um modelo de objeto atua como paradigma subjacente, o aplicativo é representado como um conjunto de objetos em interação. Cada objeto é alocado explicitamente a uma plataforma de har- dware (ou seja, não consideramos casos em que um objeto se estende logicamente além dos limites do computador). 35 Middleware para suporte de aplicações baseadas em objetos. Fonte: Elaborada pelo autor (2021). O middleware oculta a heterogeneidade que ocorre em um sistema distribuído. Essa he- terogeneidade existe em diferentes lugares, a saber: • Linguagens de programação: diferentes objetos podem ser desenvolvidos em diferentes linguagens de programação. • Sistema operacional: os sistemas operacionais têm características e recursos diferentes. • Arquiteturas de computador: os computadores diferem em seus detalhes técni- cos (por exemplo, representações de dados). • Redes: diferentes computadores são interligados por meio de diferentes tecnolo- gias de rede. O middleware supera essa heterogeneidade, oferecendo funcionalidade igual em todos os pontos de acesso. Os aplicativos têm acesso a essa funcionalidade por meio de uma Interface de Programação de Aplicativos – API. Como a API depende da linguagem de programação na qual o aplicativo é escrito, ela deve ser adaptada às condições de cada linguagem de programação suportada pelo middleware. Um programador de aplicativos normalmente vê o middleware como uma biblioteca de programa e um conjunto de ferramentas. A forma que eles assumem depende natural- mente do ambiente de desenvolvimento que o programador está usando. Junto com a 36 linguagem de programação selecionada, isso também é afetado pelo compilador/inter- pretador real usado para desenvolver um aplicativo distribuído. Padronização de um middleware Se projetássemos um middleware para uma rede global e mundial, encontraríamos características especiais que diferem daquelas de um sistema distribuído geografica- mente restrito. Em nível global, o middleware abrange vários domínios tecnológicos e políticos e não se pode mais presumir que existe uma tecnologia homogênea dentro de um sistema distribuído. Devido à heterogeneidade e à complexidade associadas a ele, não podemos assumir que um único fornecedor é capaz de fornecer middleware na forma de produtos para todos os ambientes. Do ponto de vista da política de mercado, geralmente é desejável evitar o monopólio de um produto e apoiar a inovação por meio da competição. No entanto, a im- plementação de middleware por meio de vários produtos concorrentes não deve resultar em soluções parciais que não sejam compatíveis. A compatibilidade só é possível se todos os fornecedores de middleware aderirem a um padrão. Este deve, portanto, estipular a especificação de um produto — uma descrição abstrata de um comportamento desejado que permita certo grau de liberdade na execu- ção de uma implementação. Ele serve como um plano de acordo com o qual diferentes produtos (ou seja, implementações) podem ser produzidos. Uma especificação como um padrão identifica as características verificáveis de um sis- tema. Se um sistema está em conformidade com um padrão, ele está atendendo a essas características. Do ponto de vista do cliente, os padrões oferecem uma infinidade de vantagens. Em uma situação ideal, um padrão garante a independência do fornecedor, permitindo assim que o cliente escolha entre uma variedade de produtos sem ter que se comprometer com um fornecedor específico. Para os clientes, isso significa proteção dos investimentos que eles devem fazer para usar um produto. Vejamos as seguintes características que estão associadas aos padrões abertos: • Não proprietário: o padrão em si não está sujeito a quaisquer interesses comerciais. • Disponível gratuitamente: o acesso ao padrão está disponívelpara todos. • Independente de tecnologia: o padrão representa uma abstração de mecanis- mos técnicos concretos e apenas define um sistema na medida necessária para compatibilidade entre produtos. 37 • Processo de criação democrática: a criação e subsequente evolução da norma não são regidas pelo domínio de uma empresa, mas ocorre por meio de proces- sos democráticos. • Disponibilidade do produto: um padrão só é eficaz se houver produtos para ele. A este respeito, existe uma relação próxima entre um padrão e os produtos que po- dem ser tecnicamente usados em conjunto com ele. A importância do middleware é tamanha por conta de se ser um software que oferece serviços e recursos comuns a aplicações, além da cloud computing. Com ela vem vários benefícios, aumentando à complexidade devida dar a possibilidade de implantar aplica- ções em diversas infraestruturas, sejam elas on-premises até as nuvens públicas. Para ampliar o seu conhecimento veja o material complementar da Unidade 1, disponível na midiateca. MIDIATECA Esta unidade trouxe conhecimento suficiente para que você amplie sua visão em relação a sistemas distribuídos: os modelos físicos de computadores e dis- positivos que constituem um sistema, os modelos arquitetônicos que descre- vem um sistema em termos de computação e tarefas de comunicação e os modelos fundamentais com uma perspectiva abstrata com o intuito de des- crever soluções para problemas individuais enfrentados pela maioria dos siste- mas distribuídos. Estes conceitos darão a possibilidade de você ser capaz de controlar e notificar uma condição atual de dispositivos genéricos, como a IoT (Internet das Coisas) e pensar com componentes físicos e lógicos, replicando para APIs ao ponto de serem acionadas aos seus respectivos dispositivos. NA PRÁTICA 38 Resumo da Unidade 1 Nesta unidade, ao notarmos acerca do termo arquitetura de software, podemos per- ceber que havia como citação a estruturação do software por meio de camadas ou de módulos em um único computador. Vimos que, quando temos um modelo de arquite- tura, também temos a abstração das funções dos componentes individuais no sistema distribuído. Por fim, podemos dizer que a arquitetura de software interligada aos servi- ços oferecidos traz a finalidade de uma visão orientada a processos e serviços, tendo assim, camadas de serviços. 39 Referências KON, F.; COSTA, F.; BLAIR, G. and CAMPBELL, R. The case for reflective middliware. Comms. ACM, Vol. 45, Nº 6, 2002. p. 33-38. LAMPORT, L. How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Program. IEEE Trans. Comput. 28 (9): 690–691, 1979. MEHTA, N.; MEDVIOOVIC, N.; PHADKE, S.: Towards A Taxonomy Of Software Connec- tors. Proc. 22nd Int’l Conj. On Software Engineering. (Limeric, Ireland). New York, NY: ACM Press, 2000. p. 178-187. OMG: UML 2.0 Superstructure Specification. OMG Document ptc/04-IO-02, Object Ma- nagement Group, Framingham, MA, Oct., 2004b. SALTZER, J.H.; REED, D.P.; CLARKE, D. End-to-end arguments in system design. ACM Transactions on Computer Systems, v. 2, n. 4, 1984. p. 277-88. SHAW, M.; and CLEMENTS, P. A Field Guide to Boxology: Preliminary Classification of Architectural, Styles for Software Systems. Proc. 21st Int’l Compo Softw. & Appl. Conf. 1997. pp. 6-13. TANEBAUM, A. S.; STEEN, M. V. Sistemas Distribuídos: princípios e paradigmas. 2 ed. São Paulo: Pearson, 2008. Comunicação entre processos UNIDADE 2 41 Para que se tenha comunicação entre processos distribuídos, é necessário comutar mensagens de maneira mais simples de comunicação entre esses processos. A comu- nicação entre processos é o core de todo sistema distribuído. Não há explicação sobre estudar sistemas distribuídos sem analisar de forma cuidadosa os modos pelos quais processos em máquinas diferentes podem trocar informações. É importante salientar que tais modos têm como base a troca de mensagens na co- municação em sistemas distribuídos, de baixo nível, como a oferecida pela rede subja- cente. Existe a dificuldade no expressar essa troca de mensagens em comparação ao uso primitivo baseado em memória compartilhada, como a disponível para plataformas não distribuídas. INTRODUÇÃO Nesta unidade você será capaz de: • Descrever como os processos se comunicam em um sistema distribuído. OBJETIVO 42 Problemas de ligação em rede para sistemas distribuídos Embora muito seja falado sobre falhas, a realidade é ainda mais sombria. Podemos ten- tar transformar nosso pessimismo ao máximo e presumir que tudo o que pode dar erra- do, dará errado. Vamos tentar? Imagine que os operadores de sistemas experientes dirão que essa é uma suposição razoável. Se você perguntar com educação, eles podem contar algumas histó- rias assustadoras enquanto cuidam de suas cicatrizes de batalhas anteriores. Trabalhar com sistemas distribuídos, fundamentalmente, é diferente de escrever softwa- re em um único computador e a principal diferença é que existem muitas maneiras novas e interessantes de as coisas darem errado. Neste tópico teremos uma ideia dos problemas que surgem na prática e uma com- preensão das situações em que podemos e não podemos confiar. No final, nossa ta- refa como engenheiros será construir sistemas que façam seu trabalho (ou seja, que atendam às garantias que os usuários esperam), apesar de tudo dar errado. É possível vivenciar alguns exemplos de algoritmos que podem fornecer tais garantias em um sistema distribuído. Porém, primeiro, neste tópico, devemos entender quais são os de- safios que enfrentamos. Trataremos de uma visão geral totalmente pessimista e deprimente das coisas que po- dem dar errado em um sistema distribuído. Analisaremos os problemas com redes, pro- blemas de relógios e temporização, e vamos discutir em que grau eles são evitáveis. As consequências de todos esses problemas são desorientadoras, por isso explorar como pensar sobre o estado de um sistema distribuído e como raciocinar sobre coisas que aconteceram é importante. Falhas e falhas parciais Quando se escreve um programa em um único computador, ele normalmente se com- porta de forma bastante previsível: funciona ou não funciona. O software com erros pode dar a impressão de que o computador está às vezes “tendo um dia ruim” (um pro- blema que geralmente é corrigido por uma reinicialização), mas isso é principalmente uma consequência de um software mal escrito. 43 Não há nenhuma razão fundamental para que o software em um único computador deva ser instável: quando o hardware está funcionando corretamente, a mesma opera- ção sempre produz o mesmo resultado: é determinística. Se houver um problema de hardware, por exemplo, problema de memória ou um conector solto, a consequência é geralmente uma falha total do sistema, tal como, kernel panic, “tela azul da morte”, falha na inicialização. Um computador individual com um bom software geralmente está total- mente funcional ou totalmente danificado, mas não é algo intermediário. Esta é uma escolha deliberada no design de computadores: se ocorrer falha interna, pre- ferimos que um computador trave completamente em vez de retornar um resultado er- rado, porque resultados errados são difíceis e confusos de lidar. Logo, os computadores ocultam a realidade física nebulosa na qual são implementados e apresentam um mode- lo de sistema idealizado que opera com perfeição matemática. Uma instrução CPU sempre faz a mesma coisa. Se você gravar alguns dados na me- mória ou disco, esses dados permanecerão intactos e não serão corrompidos aleato- riamente. Esse objetivo de projeto de computação sempre correta remonta ao primeiro computador digital. Quando você está escrevendo um software que roda em vários computadores conecta- dos por uma rede, a situação é fundamentalmente diferente. Em sistemas distribuídos, não estamos mais operando em um modelo de sistema idealizado — não temos escolha, a não ser confrontar a confusa realidade do mundo físico. E no mundo físico, uma gamaextraordinariamente ampla de coisas pode dar errado. Em um sistema distribuído pode muito bem haver algumas partes do sistema que estão danificadas de alguma forma imprevisível, embora outras partes do sistema estejam fun- cionando bem. Isso é conhecido como falha parcial. A dificuldade é que as falhas parciais não são determinísticas: se você tentar fazer algo envolvendo vários nós e a rede, às vezes pode funcionar e às vezes falhar de forma imprevisível. Como veremos, você pode nem saber se algo deu certo ou não, pois o tempo que uma mensagem leva para trafegar pela rede também não é determinístico! Esse não determinismo e possibilidade de falhas parciais é o que torna os sistemas dis- tribuídos difíceis de trabalhar. 44 Computação em nuvem e supercomputação Existe um espectro de filosofias sobre como construir sistemas de computação em grande escala. Veremos alguns deles: • Em um extremo da escala está o campo da computação de alto desempenho (HPC). Supercomputadores com milhares de CPUs são normalmente usados para tarefas de computação científica intensivas em computação, como previsão do tempo ou dinâmica molecular (simulação do movimento de átomos e moléculas). • No outro extremo está a computação em nuvem, que não é muito bem definida, mas muitas vezes associada a datacenters multilocatários, computadores de com- modities conectados a uma rede IP (geralmente Ethernet), alocação de recursos elástica/sob demanda e medida faturamento. • Os datacenters corporativos tradicionais ficam em algum lugar entre esses ex- tremos. Com essas filosofias vêm abordagens muito diferentes para lidar com as falhas. Em um supercomputador, um trabalho normalmente verifica o estado de sua computação para armazenamento durável de tempos em tempos. Se um nó falhar, uma solução comum é simplesmente parar toda a carga de trabalho do cluster. Depois que o nó defeituoso é reparado, a computação é reiniciada a partir do último ponto de verificação. Todavia, um supercomputador é mais parecido com um computador de nó único do que um sistema distribuído: ele lida com a falha parcial, permitindo que se transforme em fa- lha total — se qualquer parte do sistema falhar, apenas deixe tudo falhar (como um kernel panic em uma única máquina). Os sistemas para implementação de serviços de internet são diferentes dos supercom- putadores. Vamos entender essas diferenças. • Muitos aplicativos relacionados à internet estão on-line, no sentido de que preci- sam ser capazes de atender aos usuários com baixa latência a qualquer momento. Tornar o serviço indisponível — por exemplo, parar o cluster para reparo — não é aceitável. Em contraste, trabalhos off-line (em lote), como simulações meteorológi- cas, podem ser interrompidos e reiniciados com impacto bastante baixo. 45 • Os supercomputadores são normalmente construídos a partir de hardware espe- cializado, onde cada nó é bastante confiável e os nós se comunicam por meio de memória compartilhada e acesso remoto direto à memória (RDMA). Por outro lado, os nós em serviços em nuvem são construídos a partir de máquinas comuns, que podem fornecer desempenho equivalente a um custo menor devido a economias de escala, mas também apresentam taxas de falha mais altas. • Grandes redes de datacenters são frequentemente baseadas em IP e Ethernet, organizadas em topologias Clos para fornecer alta largura de banda de bissecção. Os supercomputadores costumam usar topologias de rede especializadas, como malhas multidimensionais e toruses, que proporcionam melhor desempenho para cargas de trabalho de HPC com padrões de comunicação conhecidos. • Quanto maior se torna um sistema, mais provável que um de seus componentes esteja quebrado. Com o tempo, coisas quebradas são consertadas e coisas novas quebram, mas em um sistema com milhares de nós, é razoável supor que algo está sempre quebrado. Quando a estratégia de tratamento de erros consiste simples- mente em desistir, um grande sistema pode acabar gastando muito do seu tempo recuperando-se de falhas em vez de fazer um trabalho útil. • Se o sistema pode tolerar nós com falha e ainda continuar trabalhando como um todo, esse é um recurso muito útil para operações e manutenção: por exemplo, você pode realizar uma atualização contínua, reiniciando um nó por vez, enquanto o ser- viço continua atendendo aos usuários sem interrupção. Em ambientes de nuvem, se uma máquina virtual não estiver funcionando bem, você pode simplesmente elimi- ná-la e solicitar uma nova (esperando que a nova seja mais rápida). • Em uma implantação distribuída geograficamente (mantendo os dados geografi- camente próximos aos usuários para reduzir a latência de acesso), a comunicação provavelmente vai pela internet, que é lenta e não confiável em comparação com as redes locais. Os supercomputadores geralmente assumem que todos os seus nós estão próximos. Se quisermos fazer os sistemas distribuídos funcionarem, devemos aceitar a possibilida- de de falha parcial e construir mecanismos de tolerância a falhas no software. Em outras palavras, precisamos construir um sistema confiável a partir de componentes não con- fiáveis. (Não existe confiabilidade perfeita, então precisamos entender os limites do que podemos prometer de forma realista.) 46 Mesmo em sistemas menores que consistem em apenas alguns nós, é importante pen- sar em falha parcial. Em um sistema pequeno, é bastante provável que, na maior parte das vezes, a maioria dos componentes esteja funcionando corretamente. No entanto, mais cedo ou mais tarde alguma parte do sistema ficará com defeito e o software terá que lidar com isso de alguma forma. O tratamento da falha deve fazer parte do design do software e você (como operador do software) precisa saber qual comportamento espe- rar do software, no caso de uma falha. Não seria sensato presumir que as falhas são raras e simplesmente esperar pelo melhor. É importante considerar uma ampla gama de falhas possíveis, mesmo as bastante im- prováveis, e criar artificialmente tais situações em seu ambiente de teste para ver o que acontece. Em sistemas distribuídos, suspeita, pessimismo e paranoia compensam. Redes não confiáveis Os sistemas distribuídos que falamos são sistemas sem compartilhamento, ou seja, um monte de máquinas conectadas por uma rede. A rede é a única maneira pela qual essas máquinas podem se comunicar — presumimos que cada máquina tem sua própria me- mória e disco, e uma máquina não pode acessar a memória ou disco de outra, exceto fazendo solicitações para um serviço pela rede. Ter nada compartilhado não é a única maneira de construir sistemas, mas tornou-se a abordagem dominante para construir serviços de internet, por várias razões: • É comparativamente barato porque não requer hardware especial. • Faz uso de serviços de computação em nuvem comoditizados. • Atinge alta confiabilidade por meio da redundância em vários datacenters distri- buídos geograficamente. A internet e a maioria das redes internas em datacenters (geralmente Ethernet) são redes de pacotes assíncronos. Nesse tipo de rede, um nó pode enviar uma mensagem (um pacote) para outro nó, mas a rede não dá nenhuma garantia de quando ela chegará ou se chegará. Se você enviar uma solicitação e esperar uma resposta, muitas coisas podem dar errado. Veremos alguns erros a seguir. Observe a figura adiante. 1. Sua solicitação pode ter sido perdida (talvez alguém desconectou um cabo de rede). 47 2. Sua solicitação pode estar esperando em uma fila e será entregue mais tarde (talvez a rede ou o destinatário estejam sobrecarregados). 3. O nó remoto pode ter falhado (talvez tenha travado ou tenha sido desligado). 4. O nó remoto pode ter parado de responder temporariamente (talvez esteja pas- sando por uma longa pausa na coleta de lixo; consulte “Pausas do processo” na página 309), mas começará a responder novamente mais tarde. 5. O nó remoto pode ter processado sua solicitação, mas a resposta foi perdida na rede(talvez um switch de rede tenha sido configurado incorretamente). 6. O nó remoto pode ter processado sua solicitação, mas a resposta foi atrasada e será entregue mais tarde (talvez a rede ou sua própria máquina esteja sobrecarregada). Comunicação entre nós. Fonte: Elaborada pelo autor (2021). Sobre a imagem, considere: Se você enviar uma solicitação e não obtiver uma resposta, não é possível distinguir se (a) a solicitação foi perdida, (b) o nó remoto está inativo ou (c) a resposta foi perdida. O remetente nem sabe dizer se o pacote foi entregue — a única opção é o destinatário enviar uma mensagem de resposta, que, por sua vez, pode ser perdida ou atrasada. Es- ses problemas são indistinguíveis em uma rede assíncrona, a única informação que você tem é que ainda não recebeu uma resposta. Se você enviar uma solicitação para outro nó e não receber uma resposta, é impossível dizer o porquê. Cliente (b) (c)(a) ??? ??? ??? ok Rede Serviço tempo nó que não responde 48 A maneira usual de lidar com esse problema é por tempo limite: depois de algum tempo, você desiste de esperar e presume que a resposta não chegará. No entanto, quando ocorre um tempo limite, você ainda não sabe se o nó remoto recebeu sua solicitação ou não (e se a solicitação ainda está na fila em algum lugar, se ainda pode ser entregue ao destinatário, mesmo que o remetente tenha desistido). Falhas de rede na prática Há décadas construímos redes de computadores e pode-se esperar que agora já tenha- mos descoberto como torná-las confiáveis. No entanto, parece que ainda não conseguimos. Existem alguns estudos sistemáticos e muitas evidências anedóticas mostrando que problemas de rede podem ser surpreendentemente comuns, mesmo em ambientes con- trolados, como um datacenter operado por uma empresa. Por exemplo um estudo em um datacenter de médio porte encontrou cerca de 12 falhas de rede por mês, das quais metade desconectava uma única máquina e metade desconectava um rack inteiro. Outro estudo mediu as taxas de falha de componentes como switches top-of-rack, switches de agregação e balanceadores de carga. Ele descobriu que adicionar equipamento de rede redundante não reduz as falhas tanto quanto você poderia esperar, uma vez que não pro- tege contra erro humano (por exemplo, interruptores configurados incorretamente), que é uma das principais causas de interrupções. Os serviços de nuvem pública, como o EC2, são notórios por terem falhas de rede tran- sitórias frequentes, mas redes de datacenter privadas bem gerenciadas podem ser am- bientes mais estáveis. No entanto, ninguém está imune a problemas de rede: por exem- plo, um problema durante uma atualização de software para um switch pode acionar uma reconfiguração da topologia de rede, durante a qual os pacotes de rede podem ser atrasados por mais de um minuto. Os tubarões podem morder cabos submarinos e danificá-los. Outras falhas surpreendentes incluem uma interface de rede que às vezes descartam todos os pacotes de entrada, mas enviam os pacotes de saída com sucesso: só porque um link de rede funciona em uma direção não garante que também esteja funcionando na direção oposta. Mesmo que as falhas de rede sejam raras em seu ambiente, o fato de que essas falhas po- dem ocorrer significa que seu software precisa ser capaz de lidar com elas. Sempre que qualquer comunicação ocorre em uma rede, ela pode falhar; não há como contornar isso. Se o tratamento de erros de falhas de rede não for definido e testado, coisas arbitraria- mente ruins podem acontecer. Por exemplo, o cluster pode se tornar um impasse e ficar 49 permanentemente incapaz de atender às solicitações, mesmo quando a rede se recupe- rar, ou pode até mesmo excluir todos os seus dados. Se o software for colocado em uma situação imprevista, ele pode fazer coisas inesperadas e arbitrárias. Lidar com falhas de rede não significa necessariamente tolerá-las: se a sua rede é nor- malmente bastante confiável, uma abordagem válida pode ser simplesmente mostrar uma mensagem de erro aos usuários enquanto sua rede está tendo problemas. No en- tanto, você precisa saber como seu software reage a problemas de rede e garantir que o sistema possa se recuperar deles. Pode fazer sentido desencadear problemas de rede deliberadamente e testar a resposta do sistema. 50 Representação externa de dados e empacotamento O acondicionamento de informações nos programas em execução é retratado como es- truturas de dados — por exemplo, por conjuntos de objetos interconectados —, enquanto as informações nas mensagens consistem em sequências de bytes. Independentemente da forma comunicável utilizada, as estruturas de dados precisam ser achatadas (modi- ficadas em uma sequência de bytes) antes da transferência e restabelecida na chegada. Os itens de dados primitivos individuais transmitidos em mensagens podem ser valores de dados de diversos tipos contrários e nem todos os computadores ajuntam valores primitivos, como inteiros, na mesma ordem. A representação de números de ponto flu- tuante também difere entre as arquiteturas. Existem duas variantes para a ordenação de inteiros: a chamada ordem big-endian, em que o byte mais significativo vem primeiro, e a ordem little-endian, na qual vem por último. Outra questão é o conjunto de códigos usados para representar caracteres. Por exemplo, a maioria das aplicações em sistemas como o UNIX usa codificação de caracteres ASCII, pegando um byte por caractere, en- quanto o padrão Unicode permite a representação de textos em muitos idiomas diferen- tes e leva dois bytes por caractere. Um dos seguintes métodos pode ser usado para permitir que quaisquer dois computa- dores troquem valores de dados binários: • Os resultados são transformados para um modelo externo acordado antes da transferência e transformados para o formato local no recebimento. Se forem do mesmo estilo os dois computadores, a transformação para o formato externo pode ser ocultada. • Os resultados são transmitidos no formato do remetente, juntamente com a indi- cação do formato utilizado, e o destinatário converte os valores, se necessário. Observe, entretanto, que os bytes em si nunca são alterados durante a transmissão. Para suportar RMI ou RPC, qualquer tipo de dados que pode ser passado como um argu- mento ou retornado como um resultado deve ser capaz de ser nivelado e os valores de dados primitivos individuais representados em um formato acordado. Um padrão acor- dado para a representação de estruturas de dados e valores primitivos é chamado de representação de dados externos. 51 Marshalling (empacotamento) é o processo de pegar uma coleção de elementos de dados e construir em uma forma adequada para transmissão em uma mensagem. Des- marcar é a execução de desmontá-los na chegada para construir uma coleção equiva- lente de itens de dados no destino. Logo, o marshalling consiste na tradução de itens de dados estruturados e valores originais em uma representação de dados externa. Da mesma forma, o desempacotamento consiste no desenvolvimento de valores originais a partir de sua representação de dados externa e na reconstrução das estruturas de dados. Podemos citar três abordagens alternativas para representação de dados externos e em- pacotamento, que são: • 1ª abordagem: o conteúdo de dados comum do CORBA indica um conteúdo ex- terno para os tipos estruturados e primitivos, que podem ser transcorridos como os argumentos e resultados de invocações de métodos remotos no CORBA. Ele pode ser empregado por uma variedade de linguagens de programação. • 2ª abordagem: serialização de objetos Java. Indica o achatamento e a represen- tação de dados externos de qualquer objeto único ou árvore de objetos que podem precisar ser transmitidos em uma mensagem ou armazenados em um disco. Deve ser usado apenas por Java. • 3ª abordagem: XML (Extensible Markup Language), que indica um formato textual para caracterizar dados estruturados. Ele foi originalmente planejado para documen-
Compartilhar