Conceitos Fundamentais de Programação Distribuída
Classificado em Computação
Escrito em em
português com um tamanho de 14,08 KB
1) Programação Distribuída
Desenvolvimento e execução de sistemas que operam de forma concorrente e descentralizada em um ou mais computadores. Um dos maiores exemplos atuais são os mineradores de *Bitcoin*. É praticamente impossível executá-los em apenas um computador devido ao poder de processamento necessário. Aí, entra a programação distribuída, descentralizando em mais computadores e conseguindo suprir a demanda de processamento.
- Aspectos:
- Hardware: autonomia/independência.
- Software: Sistema Único.
2) Características, Vantagens e Desvantagens
Características
- Hardware autônomo; software cria abstrações, vendo-os como um sistema único.
- Execução concorrente.
- Compartilhamento de recursos.
- Troca de mensagens.
- Inexistência de relógio global.
- Falhas independentes.
- Componentes e recursos redundantes.
Vantagens
- Maior velocidade: por ter execuções concorrentes e compartilhamento de recursos.
- Confiabilidade: por ter redundância.
- Compartilhamento de dados: por ter recursos compartilhados.
Desvantagens
- Depuração mais complicada: por ter vários sistemas, é necessário saber onde exatamente está o erro/problema, o que torna o processo mais difícil.
- Desenvolvimento e gerenciamento mais complexo: por ser vários sistemas.
- Dificuldade na segurança: difícil garantir que todos os *endpoints* estejam seguros.
3) Desafios e Soluções em Sistemas Distribuídos
- Heterogeneidade: Diferentes *hardwares*, diferentes SOs, diferentes dados. Solução: middleware.
- Padronização/Abertura: Padrões abertos com especificação e documentação. Solução: Independência de fornecedor.
- Segurança: Preciso garantir confidencialidade, integridade e disponibilidade. Solução: Soluções de criptografia.
- Escalabilidade: O sistema deve funcionar sem problemas, independente do número de usuários, dados ou recursos. Solução: Usar estruturas de dados adequadas.
- Tratamento de Falhas: Manter o sistema disponível sob qualquer circunstância. Solução: Redundância.
- Concorrência: Processo natural de um SD que, para funcionar, deve ter a exclusão mútua no acesso a recursos compartilhados.
- Transparência: Esconder a separação física dos componentes a fim de parecer um sistema único. Ex: para transparência de concorrência, exige-se exclusão mútua.
4) Middleware e Gerenciamento de Estado
Middleware
Camada entre o SO e as aplicações que mascara a heterogeneidade e provê um modelo mais conveniente de programação. Ex: Sun RPC, RMI, etc.
Stateless (Sem Estado)
Significa que o estado do serviço não é levado em consideração entre duas conexões remotas. Cada requisição carrega suas próprias credenciais, não há necessidade de estabelecer/fechar conexões. É simples, e a queda do servidor não afeta os clientes.
Stateful (Com Estado)
Requisições são orientadas à conexão, isto é, cada requisição está orientada a alterações feitas previamente. Servidores mantêm informações prévias, o que gera problemas com quedas de servidores/clientes.
5) Classificação de Flynn e Modelos de Memória
Classificação de Flynn
- SISD: Um único fluxo de instruções sobre um único fluxo de dados. Ex: Von Neumann.
- MISD: Múltiplas P (unidades de processamento) com suas C (unidade de controle) recebendo fluxo diferente de dados. As Ps executam diferentes instruções sobre o mesmo fluxo de dados. Ex: *Systolic Array*.
- SIMD: Processamento feito por 1 P e 1 C. A mesma instrução é enviada para diversas Ps. As Ps funcionam em paralelo e uma única instrução é executada sobre diferentes dados. SIMD explora paralelismo de dados. Ex: Máquinas Vetoriais.
- MIMD: Cada C recebe 1 fluxo de instruções e repassa para P para que seja executado sobre seu fluxo. Cada P executa seu próprio programa sobre seus próprios dados. Maior flexibilidade e paralelismo de processos. Ex: Servidores dual, quad, etc.
Modelos de Memória
- Memória Distribuída: Implementada com vários módulos, módulo próximo do processador.
- Memória Centralizada: Encontra-se à mesma distância de todos os processadores.
- Memória Compartilhada: Único espaço de endereçamento usado para comunicação entre processadores; processos acessam variáveis compartilhadas (*Load/Store*).
- Memória Não-Compartilhada: Múltiplos espaços de endereçamento privados. Comunicação com troca de mensagens (*Send/Receive*).
6) Arquiteturas de Sistemas Paralelos
Multiprocessadores
Máquina paralela feita a partir de processadores convencionais. Todos P acessam memórias compartilhadas através de uma rede de interconexão. Possui apenas um espaço de endereçamento (*Load/Store*).
- UMA (Uniform Memory Access): Memória centralizada, latência de acesso igual a todas as memórias, barramento é usado para comunicação.
- NUMA (Non-Uniform Memory Access): Memória distribuída, endereço de endereçamento único, acesso não uniforme, distância variável, tempo de acesso à memória local baixo e menor que às demais.
Multicomputadores
São construídos a partir da replicação de TODA a arquitetura convencional e não só dos processadores. São compostos por 'armários' com diversas 'gavetas', onde cada uma possui vários processadores. Processadores possuem memória local de acesso restrito. Comunicação feita por troca de mensagens.
- NoRMA (Normative Reference Model Architecture): Replicação inteira da arquitetura que faz com que cada nó só consiga alcançar sua memória local.
7) Comunicação entre Processos (IPC)
Comunicação entre processos.
- Memória Compartilhada: Os processos compartilham variáveis e trocam informações através do uso delas.
- Sem Memória Compartilhada: Os processos compartilham informações através de troca de mensagens. O S.O é responsável pelo mecanismo de comunicação entre os processos.
8) Requisitos para Troca de Mensagens
Para um sistema conseguir realizar a troca de mensagens é preciso que ele tenha:
- Simplicidade: Construção de novas operações que operem com as existentes para maior simplificação.
- Semântica Uniforme: Comunicação local e remota através de funções o mais próximas possíveis.
- Eficiência: Reduzir o número de mensagens à menor quantidade possível.
- Confiabilidade: Garantir a entrega da mensagem.
- Flexibilidade: Possibilidade de usar só a funcionalidade requerida.
- Segurança: Suporte à autenticação, privacidade.
- Portabilidade: Disponibilidade de IPC em plataformas heterogêneas.
9) Sincronização de Mensagens
Na sincronização de mensagens, haverá dois tipos: síncrona e assíncrona:
- Quando
sendereceivesão bloqueantes, chamamos de síncrona. - Caso contrário, chamamos de assíncrona.
Com receive bloqueante, o processo receptor fica bloqueado até a chegada da mensagem. O problema disso é ficar bloqueado para sempre em caso de *time-out*.
Com receive não bloqueante, o processo receptor informa ao núcleo onde a mensagem deve ser armazenada e segue adiante. A informação da recepção da mensagem é feita por *polling* ou interrupção.
10) Endereçamento e Bufferização
Endereçamento
Há dois tipos: explícito e implícito.
- Explícito: O processo com o qual se quer comunicar é explicitamente identificado. O *sender* identifica o *receiver* e o *receiver* identifica o *sender*.
- Implícito: O processo com o qual se quer comunicar não é identificado (Ex: envio para qualquer *receiver* que desempenhe uma função/serviço). O *sender* identifica o *receiver* e o *receiver* recebe de qualquer *sender*.
Métodos de Identificação de Processo
Para identificar um processo é necessário usar dois métodos:
- Transparente: Identificador do processo não deve ter embutida informação de localização do processo. Há a necessidade de realizar a tradução de nomes.
- Não Transparente: Especifica o identificador da máquina. Um dos problemas pode ser se o processo migrar/mover-se, gerando *overhead*.
Bufferização
Está relacionado com o sincronismo da comunicação.
- Null Buffer: Não há espaço temporário para armazenar a mensagem. Usado apenas para comunicação síncrona.
- Single Message Buffer: Para comunicação síncrona. A ideia é manter a mensagem pronta para uso no local de destino.
- Unbounded-capacity buffer: Para comunicação assíncrona. O enviador não espera o receptor. Impossível na prática.
- Finite-bound buffer: É necessário uma estratégia para *buffer overflow*.
11) Estratégias de Confirmação de Requisição
Problema: execução de um pedido (*request*) no destinatário não tem sucesso. Há três estratégias para isso: *four-message*, *three-message*, *two-message*.
- Four-message: Há confirmação da mensagem de pedido e de resposta.
- Three-message: Há apenas confirmação da resposta.
- Two-message: A própria resposta é a confirmação.
12) Modelos de Interação em Sistemas Distribuídos
Modelo Cliente/Servidor
- Cliente: Faz a requisição.
- Servidor: Recebe a requisição.
Para qualquer comunicação, um dos lados deve iniciar a comunicação e esperar indefinidamente que o outro lado responda.
Modelo P2P (Peer-to-Peer)
São sistemas distribuídos nos quais os membros da rede são iguais em funcionalidade. Permitem que os pares compartilhem recursos diretamente, sem haver intermediários.
Os sistemas P2P devem suportar os seguintes requisitos:
- Comunicação direta entre pares.
- Nós com conectividade variável.
- Nós com autonomia parcial.
- Escalabilidade.
Ex: Skype, Napster, Torrent.
13) Arquiteturas P2P
- Arquitetura Centralizada: Utiliza um servidor central para controle da rede e publicação da pesquisa de conteúdo. Acesso feito diretamente pelos *peers*. O problema principal é ter um ponto único de falha. Ex: Napster.
- Arquitetura Descentralizada: Todos os *peers* possuem funcionalidade equivalente. Gera alto tráfego na rede e desempenho ruim das pesquisas. Ex: JXTA.
- Arquitetura Híbrida: Alguns *peers* especiais, chamados supernós, possuem papel diferenciado na rede. Eles permitem o ingresso de nós, podendo gerenciá-los, indexá-los, etc. Após localizado, um recurso pode ser obtido a partir da interação direta entre nós. A falha de um supernó pode ser tolerada, elegendo dinamicamente outro nó.
14) Comunicação em Grupo
O principal objetivo da comunicação em grupo é o envio da mensagem para um grupo de processos através de uma única ação. Os grupos devem ser dinâmicos e a mensagem é recebida por cada um de seus membros.
15) Tipos de Comunicação em Grupo
One-to-Many (Multicast)
- Grupo Aberto: Qualquer processo pode mandar mensagens para o grupo.
- Grupo Fechado: Somente membros do grupo podem mandar mensagens para o grupo.
- Multicast é normalmente assíncrono.
- Buferizada: Mensagem armazenada para o processo receptor.
- Não-buferizada: Mensagem chega e o processo receptor não está pronto; o SO descarta a mensagem.
- Comunicação indireta.
- Semântica de envio: Send-to-all (cópia da mensagem mandada para cada processo do grupo) ou *bullet-board* (mensagem endereçada a um canal, processos receptores pegam a mensagem do canal).
Ex: achar servidor oferecendo um tipo determinado de serviço.
Many-to-One
- Recepção Seletiva: Recebedor controla dinamicamente de quem quer receber.
- Recepção Não Seletiva: Recebedor quer receber de qualquer um do grupo.
Many-to-Many
- Possui entrega ordenada de mensagens. A ordenação possui serialização das mensagens.
Em *one-to-many* temos que sequenciar *multicasts*; em *many-to-one* temos que ordenar de maneira simples; em *many-to-many* são vários enviadores e vários recebedores, podendo variar no atraso, visto que depende da posição dos mesmos.
16) IP Multicast e Confiabilidade
IP Multicast: É uma comunicação *one-to-many* não confiável, pois não há a garantia de entrega das mensagens. Não há como garantir que um pacote atinja todos os usuários de um grupo *multicast*. O **JGroups** pode resolver esse problema; ele é um *framework* para comunicação em um grupo confiável, agindo como um manipulador para um determinado grupo, podendo, dessa maneira, garantir a entrega das mensagens.