A Note on Distributed Computing Jim Waldo, Geoff Wyant, Ann Wollrath, Sam Kendall (Apresentado por Aliandro Lima) Roteiro Introdução; Visão unificada de Objetos; Computação local Vs computação distribuída; Latência; Acesso à memória; Falhas parciais; Concorrência. O mito da qualidade de serviço; O caminho das pedras... (conclusões) Introdução No mundo da computação sempre existiu muito esforço para facilitar a vida do programador (tornar seu trabalho mais simples); Orientação a Objetos é um esforço nesse sentido; Esforço semelhante tem sido feito na intenção de simplificar o desenvolvimento de aplicações distribuídas (Objetos distribuídos). Orientação a Objetos O conceito de Orientação a objetos considera vários aspectos: Especificação de um conjunto de interfaces para um objeto; Especificação de uma semântica para as operações em um objeto; Encapsulamento, polimorfismo, herança... Porém, não contempla localização: Localização costuma ser tratado como um aspecto de implementação; Localização Local Computing = mesmo espaço de endereçamento; Distributed Computing = espaços de endereçamento diferentes, possivelmente em máquinas diferentes; Distributed ≠ concorrente; Visão unificada de objetos IDL IDL Framework ou middleware Framework ou middleware Objeto A Objeto B Invocação Local = Invocação Remota Justificativa para a unificação Localidade não causa impacto na corretude de um programa; Se um programa calcula a soma de dois números, ele o fará corretamente independente de localização, desde que implementado corretamente; Esconder localidade do programador parece uma questão de implementação bastante razoável; Isso nos dá facilidade de manutenção. Princípios Existe um único paradigma de orientação a objetos, independente da localização dos mesmos; Aspectos relacionados a falhas e performance são contemplados na hora da implementação e devem ser deixados de lado na hora do projeto; A interface de um objeto é independente do contexto em que este é usado. Problema Porém, programar aplicações distribuídas não é a mesma coisa de programar aplicações locais; Unificar o paradigma de comunicação com o paradigma de linguagem não é suficiente para facilitar a programação distribuída, pois comunicação não é a parte difícil; Dificuldades em computação distribuída Lidar com falhas parciais na ausência de um gerente central de recursos; Garantir performance e lidar com problemas de concorrência; Lidar com diferentes formas de acesso à memória para objetos locais e distribuídos. Local and Distributed Computing Latência; Acesso à memória; Falhas parciais; Concorrência. Latência Diferença óbvia; Diferença em torno de quatro ou cinco ordens de magnitude; Ignorar tal diferença pode trazer sérios problemas de performance; É preciso considerar latência na hora de escolher que objetos de aplicação podem ser remotos e quais devem ser agrupados proximamente. Latência Logo, considerar latência consiste em inserir um passo extra no desenvolvimento de uma aplicação distribuída: identificar o padrão de comunicação entre os objetos que formam a aplicação. Ferramentas são necessárias para ajudar nessa tarefa (identificar padrões na comunicação das entidades); Latência Pode-se argumentar que no futuro, a diferença de tempo entre chamadas locais e remotas será indistinguível; No entanto, latência não é a única diferença entre chamadas locais e remotas. É apenas a mais óbvia; Por ser a mais óbvia, muitos a consideram como a única; Acesso à memória Ponteiros x Referências; Ponteiros em um espaço de endereçamento local não são válidos em outro espaço (remoto) de endereçamento; Neste caso, temos duas opções: O middleware controlar todos os acessos à memória; ou Tornar explícito para o programador a diferença entre acessos locais e remotos. Acesso à memória Para se ter uma visão unificada, é possível: Prover memória compartilhada distribuída; Eliminar o uso de ponteiros, usando objetos sempre que um ponteiro era antes usado. Eliminar ponteiros muda o paradigma local. Programadores precisarão ter um novo estilo de programação. Como referenciar remotamente o que não é objeto? Acesso à memória Se não é possível manter uma visão unificada, o programador precisa saber disso; Se a visão é unificada, mas muda o paradigma local, o programador também precisa saber disso; Falhas parciais É logicamente possível que as diferenças referentes à latência e acesso à memória sejam escondidas por uma visão unificada; Entretanto, não parece ser logicamente possível fazer o mesmo para esconder as diferenças referentes a falhas e concorrência. Falhas em sistemas locais Podem ser falhas totais: ou detectáveis através de algum gerente de recursos central: afetam todas as entidades que executam em conjunto em uma aplicação. Sistema operacional ou o próprio “main” do programa. É fácil determinar qual erro aconteceu. Falhas em sistemas distribuídos Falhas parciais: Um componente falha (máquina, link, processo...) e outro continua executando (falhas independentes); Não existe uma entidade comum que possa determinar quando um componente falhou e avisar a todos os outros; É mais difícil determinar o erro exato; Falha de um link é indistinguível de uma falha de processo. Falhas em sistemas distribuídos É preciso assegurar que o estado do sistema inteiro é consistente após uma falha; Não temos isso em computação local; As interfaces do sistema devem ser projetadas de forma que seja possível reagir a uma falha de maneira consistente; interfaces para identificar a causa de uma falha; Interfaces para reconstruir um estado consistente diante de uma falha. Buscando um modelo unificado Alternativa 1: Tratar todos os objetos como sendo locais; Projetar as interfaces como se a comunicação fosse sempre local; Sistemas distribuídos neste modelo se comportam de maneira não determinística diante de falhas parciais, que continuam existindo e são ignoradas. Buscando um modelo unificado Alternativa 2: Projetar todas as interfaces como se a fossem remotas; Um sistema que usa esse modelo se comporta deterministicamente em relação a falhas totais e parciais; No entanto, assumimos uma semântica desnecessária para sistemas locais. Isso vai de encontro ao propósito inicial. Concorrência Apresenta o mesmo problema visto em relação a falhas; Um objeto remoto precisa tratar execução concorrente de métodos; Temos duas escolhas: Ignorar concorrência, implementar todos os objetos como locais e torcer pra que tudo dê certo; Implementar suporte a concorrência em todos os objetos, sejam eles locais ou remotos. O mito da qualidade de serviço Minha aplicação Outra aplicação O mito da qualidade de serviço A menos que exista uma operação de lock para o contexto, não se pode fazer esse código robusto. Lições do NFS Exemplo de API não distribuída (open, read, write, close) que foi reimplementada para sistemas distribuídos; Antes do NFS, sistemas de arquivos indicavam erros raros (disco cheio ou disco inutilizável): Em geral, resultavam em falha total; O NFS introduziu o conceito de falha parcial em um sistema de arquivos. Lições do NFS Mais uma vez, duas alternativas; Soft mount: expõe as falhas para a aplicação do usuário; A aplicação cliente tem que estar preparada para receber tais falhas. Caso contrário, a aplicação cliente pode corromper o sistema de arquivos; Hard mount: A aplicação fica suspensa (“congela”) até que o servidor volte; Lições do NFS Não existe maneira de eliminar hardmounting sem modificar a interface (não depende somente de implementação); NFS é uma aplicação de sucesso (usando hard-mounting), mas possui limitações de escalabilidade devido à escolha de não mudar as interfaces. É preciso que haja um administrador de sistema que identifique a falha e inicie um procedimento de recuperação. O caminho das pedras... (Conclusões) Deve-se levar a sério as diferenças entre comunicação local e remota; Unificação dos modelos gera um trade-off: Modelo semelhante ao local, mas pouco robusto para aplicações distribuídas; Modelo distribuído, muito complexo e desnecessário para programação local; É importante ter consciência das diferenças e usar um modelo próprio para o tipo de aplicação distribuída; O caminho das pedras... Tais diferenças devem ser levadas em consideração em todos os estágios de projeto e implementação; Uma linguagem que deixa bem clara a diferença entre programação local e distribuída ajuda o programador a ter essas diferenças sempre em mente; Podemos manter IDLs para descrever objetos, mas precisamos definir explicitamente quando um objeto é remoto; O caminho das pedras... A interface de um objeto remoto precisa prover meios de lidar com falhas (detecção e recuperação); O compilador da linguagem de programação deve ser “inteligente” ao gerar código para objetos locais e remotos; Ao desenvolver código, o programador tem que estar ciente se está se comunicando com um objeto local ou remoto; O caminho das pedras... O programador tem que pensar no problema de maneira diferente do que seria o problema local; Dessa forma, ao invés de perder tempo tentando unificar os modelos local e distribuído, os esforços devem ser direcionados para melhorar a performance e robustez de ambos os modelos.