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 Framework ou middleware Framework ou middleware IDL 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: afetam todas as entidades que executam em conjunto em uma aplicação. ou detectáveis através de algum gerente de recursos central: 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 re-implementada 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: Hard 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 hard-mounting 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.