Sistemas Distribuídos
Coordenação
Até agora
• Vimos algumas formas para processos sincronizarem
suas ações
• Estudamos vários problemas que podem surgir com a
concorrência de processos
Agora
• Nosso objetivo é verificar como os mecanismos de
sincronização centralizada podem ser estendidos a um
ambiente distribuído.
• Existe um curso somente sobre algoritmos distribuídos.
• Nosso objetivo é introduzir alguns dos principais
aspectos.
Sincronização de Processos
• Processos Cooperativos:
• Afetam ou são afetados por outros processos.
• Podem compartilhar um mesmo espaço de endereços lógicos, ou um mesmo arquivo.
• Endereços lógicos: threads, ou processos leves.
• Acesso concorrente a dados pode gerar inconsistência
de dados.
• Devem ser desenvolvidos mecanismos para garantir a consistência de dados compartilhados por processos cooperativos.
Jantar dos filósofos...
• Formulado por Dijkstra, 1965 • Cada filósofo come
• Usando 2 garfos simultaneamente • Usa ou larga 2 garfos
• Modela a disputa por recursos
Jantar dos filósofos...
• Algoritmo básico
• Pense até que o garfo esquerdo esteja disponível; Quando estiver, pegá-lo;
• Pense até que o garfo direito esteja disponível; Quando estiver, pegá-lo;
• Quando possuir ambos os garfos, comer por um período fixo de tempo;
• Então, coloque o garfo direito para baixo; • Então, coloque o garfo esquerdo para baixo; • Repetir desde o início.
O caso produtor/consumidor
• O caso produtor/consumidor:
• Suponha processos com memória compartilhada
• Memória consiste em um buffer de tamanho variável que
abriga itens em estoque. Variável counter indica o número de itens em estoque (itens no buffer.
• Toda vez que um produto é adicionado incrementa-se o
counter.
• Toda vez que um produto é retirado decrementa-se o counter.
O caso produtor/consumidor
// inicializacao fim = 0; ini = 0; n = 0; // codigo do produtor for (i=0; i<1000; i++) {while (n == capacidade); buf[fim] = produzir(i);
fim = (fim + 1) % capacidade; n++;
}
8
// codigo do consumidor for (i=0; i<1000; i++) {
while (n == 0) ; consumir(buf[ini]);
ini = (ini + 1) % capacidade; n--;
O caso produtor/consumidor
• Algoritmos corretos isoladamente.
• Podem causar inconsistência se rodados em
paralelo.
• Problema: Sessão Crítica!!!
• Região de código onde um processo está acessando dados compartilhados.
• Problemas de inconsistência ocorrem em sessões críticas e devem ser evitados.
O problema da sessão crítica
• Soluções para o problema da sessão crítica devem satisfazer
os requisitos:
• Exclusão mútua: Se um processo está executando uma sessão crítica (acessando dados compartilhados) os demais processos devem esperar. • Progressão:Se não há processos executando em sessão crítica, somente
processos que não estão executando no final da sessão podem competir pela sessão crítica.
• Espera limitada:existe um limite no número de vezes que outros
processos são permitidos a entrar na sessão crítica após m processo requisitar a sessão crítica.
Sessão Crítica
• Algoritmo básico
11
enter() // entra na seção crítica – bloqueia, se necessário
resourceAccesses() // acessa recursos compartilhados na seção crítica
Sistemas centralizados:
Semáforos
• Um semáforo é um tipo abstrato de dados que
possui um valor inteiro, uma lista de processos em
espera e duas operações
• P (do holandês Proberen, testar)
• V (do holandês Verhogen, incrementar)
• A implementação do semáforo deve ser atômica
• Garantido por linguagens que oferecem o recurso
Sistemas centralizados:
Semáforos
• Para garantir exclusão mútua a uma determinada
região (região crítica), cada processo deve chamar a
operação P antes de acessar tal região e chamar a
operação V após sair dessa região
• Operação P sobre um semáforo S
• Testa se o processo que executou P(S) pode ou não entrar na região crítica
• Operação V sobre um semáforo S
• Sinaliza ao semáforo que o processo não está mais na região crítica e retira outro processo da fila de espera
Sistemas centralizados:
Semáforos
• // S.valor começa com 1
• P(S)• S.valor -= 1; • Se (S.valor < 0)
• // bloqueia o processo e insere em S.fila
• V(S)
• S.valor += 1;
• Se (S.valor <= 0)
// retira algum processo de S.fila e o coloca em
execução
O caso produtor/consumidor com
semáforos
15 // inicializacao fim = 0; ini = 0; n = 0; semaforo S; S.valor = 1; // codigo do produtor for (i=0; i<1000; i++) {while (n == capacidade) ; buf[fim] = produzir(i); fim = (fim + 1) % capacidade; P(S); n++; V(S); } // codigo do consumidor for (i=0; i<1000; i++) {
while (n == 0) ; consumir(buf[ini]);
ini = (ini + 1) % capacidade; P(S);
n--; V(S); }
O caso produtor/consumidor com
semáforos
• Código do produtor:
... produzir um item ... wait(empty); wait(mutex); ...Adicionar um item no vetor ...
signal(mutex); signal(full);
O caso produtor/consumidor com
semáforos
• Código do consumidor:
wait(full); wait(mutex); ...remove nextc do buffer; ...
signal(mutex); signal(empty);
...
consome o próximo item ...
Sincronização em Sistemas
Distribuídos
• Conceitos importantes no projeto de qualquer aplicação
distribuída:
• Comunicação • Sincronização
• Sincronização em aplicações distribuídas:
• Como garantir exclusão mútua no acesso a seções críticas ? • Como garantir atomicidade na execução de uma transação
distribuída ?
• Como alocar recursos evitando a ocorrência de deadlocks ?
Sincronização em Sistemas
Distribuídos
• Sincronização em sistemas centralizados: utiliza
memória compartilhada
• Exemplos: semáforos, monitores etc
• Sincronização em sistemas distribuídos: utiliza troca
de mensagens
• Implementada via algoritmos distribuídos
• Mesmo determinar se um evento A ocorreu antes ou depois de um evento B é mais complexo do que em um sistema centralizado
Exclusão Mútua Distribuída
• Sistemas Centralizados: memória compartilhada
(semáforos, monitores etc)
• Sistemas Distribuídos: via troca de mensagens
• Requisitos:
• Segurança: No máximo um processo pode estar executando na seção crítica (SC)
• Subsistência: Um processo que requisita acesso à SC, obtém este acesso em algum momento. Ou seja, não há
deadlock ou starvation.
• Ordenação: Se uma requisição para entrar na SC
aconteceu antes de outra, a entrada de SC é garantida na ordem
Primeira Solução: Algoritmo
Centralizado
• Existe um processo coordenado (PC)
• Gerencia o acesso à SC• Processos comuns
• Antes de entrar na SC: enviam request ao PC • Quando recebem reply: entram na SC
• Quando saem da SC: enviam release ao PC
• Processo Coordenador:
• Enfileira request quando a SC ocupada
• Desenfileira request ao receber um release
Primeira Solução: Algoritmo
Centralizado
22 Server 1. Request token Queue of requests 2. Release token 3. Grant token 4 2 p 4 p 3 p p 1Primeira Solução: Algoritmo
Centralizado (cont.)
• Número de mensagens trocadas para entrar na SC:
duas (um request e um reply)
• Saída da SC: uma mensagem (release).
• Problema: processo que centraliza todas as
informações e decisões
• Solução: distribuir a fila de pedidos
• Todos os nós recebem todos os pedidos• Pedidos são ordenados pelos nós da mesma maneira
Algoritmos de Exclusão Mútua
Distribuída
• Principais Algoritmos:
• Token Ring (*) • Ricart e Agrawala (*) • Osvaldo e Roucariol • Maekawa(*) Algoritmos que serão estudados a seguir
Algoritmo Token Ring
• Supõe que os processos são organizados como um
anel lógico, por onde circula uma token
• Não exige que a topologia da rede seja em anel (anel lógico e não físico)
• Cada processo deve armazenar a configuração completa do anel
• Correção: ao processo de posse da token é
garantido o acesso à SC
Algoritmo Token Ring
• Idéia básica:
• Se um processo não deseja entrar na SC:
• Ao receber a token, repassa a mesma para seu vizinho
• Se um processo deseja entrar na SC:
• Aguarda a passagem da token e a retém
• Número de mensagens trocadas: entre 1 e n-1
Algoritmo Token Ring
27 p n p 2 p 3 p 4 To ke n p 1Algoritmo Token Ring
• Vantagens: simplicidade
• Desvantagem: tratamento de erros
• Perda da mensagem que contém a token
• Deve-se gerar a token novamente • Quando gerar ? Quem deve gerar ?
• Travamento de processos
• Deve-se reconfigurar o anel
Algoritmo de Ricart e Agrawala
• Algoritmo executado por cada processo Pi, que
compartilha uma SC ( i <= n):
• Variáveis:
estado: estado da seção crítica OSN: relógio lógico do processo
HSN: maior valor do timestamp de qualquer mensagem enviada ou recebida
• Inicialização:
estado:= livre; HSN:= 0;
1. Broadcast de mensagem request com timestamp
2. 2. Após receber um request, envia ack SE
-Não quer entrar na SC, ou
-Está tentando entrar na SC, mas seu timestamp é maior do que o enviado
(Se está na SC, coloque o request no buffer) 3. Entrar na SC, quando receber ack de todos
4. Após sair da SC, envia ack para cada request
pendent e antes de fazer nova requisição
Algoritmo de Ricart e Agrawala
Algoritmo de Ricart e Agrawala
On initialization
state := RELEASED; To enter the section
state := WANTED;
Multicast request to all processes; request processing deferred here
T := request’s timestamp;
Wait until (number of replies received = (N – 1)); state := HELD;
On receipt of a request <Ti, pi> at pj (i ≠ j)
if (state = HELD or (state = WANTED and (T, pj) < (Ti, pi)))
then
queue request from pi without replying;
else
reply immediately to pi; end if
To exit the critical section state := RELEASED;
reply to any queued requests;
Algoritmo de Ricart e Agrawala
• Número de mensagens trocadas para entrar na SC:
• 2 (n -1)
• n-1: requests • n-1: replys
• Vantagem:
• Distribuído (sem um ponto central de falha)
• Desvantagem:
Em qual situação este algoritmo pode ser ineficiente?
Algoritmo de Ricart e Agrawala
• Número de mensagens trocadas para entrar na SC:
• 2 (n -1)
• n-1: requests • n-1: replys
• Vantagem:
• Distribuído (sem um ponto central de falha)
• Desvantagem:
Em qual situação este algoritmo pode ser ineficiente?
Caso de Mútliplas requisições por um SC
Jantar dos filósofos...
• Uma solução distribuída (Kandy, 1984)
• Para cada par de filósofos que disputam um recurso, crie um garfo e dê-o adê-o filósdê-ofdê-o cdê-om a ID mais baixa (n para dê-o agente Pn).
• Cada garfo pode estar sujo ou limpo. Inicialmente, todos os garfos estão sujos.
• Quando um filósofo quer usar um conjunto de recursos (isto é, comer), esse filósofo deve obter os garfos de seus vizinhos. Para cada garfo o filósofo não tem, ele envia uma mensagem de pedido.
• Quando um filósofo com um garfo recebe uma mensagem de pedido, ele mantem o garfo se ele está limpo, mas desiste quando está sujo. Se o filósofo envia o garfo, ele limpa o garfo antes de fazê-lo.
• Depois que um filósofo acaba de comer, todos os garfos ficam sujos. Se outro filósofo havia pedido anteriormente um dos garfos, o filósofo que acabou de comer limpa o garfo e o envia.
Reforçando
1) No algoritmo do servidor central para exclusão mútua,
descreva uma situação na qual duas requisições não
são processadas na ordem acontece-antes
2) Qual o impacto na largura de banda de algoritmos de
exclusão mútua
3) O algoritmo de Ricart e Agrawala tem o problema de
que se um processo cai e não responde a uma
solicitação de outro processo para acessar recursos, a
falta de resposta será interpretada como negação de
permissão.
Solução: todas as solicitações serem respondidas imediatamente para facilitar a detecção de processos quebrados. Existem
circunstâncias em que mesmo este método é insuficiente? Discutir.
Reforçando
1) No algoritmo do servidor central para exclusão mútua,
descreva uma situação na qual duas requisições não
são processadas na ordem acontece-antes
• O Processo A envia uma solicitação rA para entrar na
Seção crítica e envia uma mensagem m para B.
• Ao receber m, B envia um pedido rB para entrar na SC.
• Para satisfazer a regra aconteceu-antes
• rA deve ser concedido antes de rB.
• No entanto, devido a atrasos de propagação de mensagem, rB chega ao servidor antes de rA,
• Eles serão atendidos na ordem oposta.
Reforçando
2) Qual o impacto na largura de banda de algoritmos
de exclusão mútua
A largura de banda será dividida pelo tempo que cada
processo “segurar” a exclusão mútua
Reforçando
3) O algoritmo de Ricart e Agrawala tem o problema de
que se um processo cai e não responde a uma solicitação
de outro processo para acessar recursos, a falta de
resposta será interpretada como negação de permissão.
Suponha que um processo nega permissão e, em seguida,
falha. O processo solicitante pensa que ele está vivo, mas a
permissão nunca virá.
Uma saída é o solicitante não bloquear realmente, mas
sim ir dormir por um período de tempo fixo, após o qual
ele examina todos os processos que negaram permissão
para ver se eles ainda estão em execução.
Algoritmos de Eleição
• Grupo de processos deve eleger um coordenador.
• Aplicações:
• Gerenciamento de réplicas,
• Algoritmos centralizados de coordenação, sincronização, etc...
• A escolha do coordenador deve ser única, mesmo
que vários processos de eleição tenham começado
simultaneamente.
Requisitos Algoritmos de Eleição
• Segurança
• Um processo conhece o processo eleito
• Subsistência
• Todos os processos participam da eleição
Algoritmo de eleição baseado em
anel
• Processos organizados em topologia anel
• Todos processos iniciam como não participantes
• Marca a si mesmo como participante e envia uma
mensagem com seu id no sentido horário
• Ao receber
• Se o id recebido é maior, encaminha para o vizinho • Se o id é menor
• Se é não participante, substitui pelo seu id
• Se é participante, não encaminha a mensagem
Algoritmo de eleição baseado em
anel
45 24 15 9 4 3 28 17 24 1Nota: Eleição iniciada pelo processo 17.
O maior identificador encontrado até então é o 24. Processos com estado participante estão escurecidos
Algoritmo Tirano (Valentão)
The bully algorithm
• Membros do grupo devem conhecer a identidade e o
endereço dos outros membros.
• Mensagens:
• Eleição: enviada para anunciar o início de uma nova eleição • Resposta: enviada em resposta a uma mensagem de eleição. • Coordenador: enviada para anunciar o coordenador.
• Um processo inicia uma eleição quando notar uma falha
no coordenador (não recebeu uma resposta a uma
requisição depois de um certo número de tentativas ou
após um certo timeout, por exemplo).
Algoritmo Tirano
The bully algorithm
• Processo inicia eleição enviando mensagem de eleição para os processos de maior prioridade. 47 eleição p 1 p2 p3 p4 C eleição resposta resposta eleição Estágio 1
Algoritmo Tirano
The bully algorithm
• Processo inicia eleição enviando mensagem de eleição para os processos de maior prioridade. • Processos respondem a mensagem e iniciam nova eleição 48 p1 p 2 p3 p4 C eleição eleição Estágio 2 p 1 p2 p3 p4 C eleição resposta resposta eleição Estágio 1 eleição resposta
Algoritmo Tirano
The bully algorithm
• Processo inicia eleição enviando mensagem de eleição para os processos de maior prioridade. • Processos respondem a mensagem e iniciam nova eleição • Processo coordenador envia mensagem de coordenador. 49 p1 p 2 p3 p4 p 1 p2 p3 p4 C eleição eleição Estágio 2 p 1 p2 p3 p4 C eleição resposta resposta eleição Estágio 1 timeout Estágio 3 eleição resposta
Algoritmo Tirano
The bully algorithm
• Processo inicia eleição enviando mensagem de eleição para os processos de maior prioridade. • Processos respondem a mensagem e iniciam nova eleição • Processo coordenador envia mensagem de coordenador. • Se nenhuma mensagem for recebida, processo se declara coordenador e envia mensagem de coordenador para os processos de menor prioridade. 50 p1 p 2 p3 p4 p 1 p2 p3 p4 C coordenador Estágio 4 C eleição eleição Estágio 2 p 1 p2 p3 p4 C eleição resposta resposta eleição Estágio 1 timeout Estágio 3 Eventualmente... p 1 p2 p3 p4 eleição resposta
Reforçando
1) Compare o algoritmo de eleição do anel com o
algoritmo valentão
2) Esboce um pseudo-código para ambos os
algoritmos.
52
Consenso
Um dos problemas mais fundamentais de SDs
Informalmente: como fazer um grupo de processos concordar em um valor
– Qual é a hora
– Fazer ou não fazer commit
– Quem é parte do grupo
– Quem é o líder do grupo
– Podemos seguir para o próximo passo do algoritmo
53
Um pouco de formalismo
Consenso:
Para chegar a um consenso, todo processo p i começa no
estado indeciso e propõe um único valor v i , extraído de
um conjunto D (i = 1, 2,..., N).
Os processos se comunicam, trocando valores. Cada
processo configura o valor de uma variável de decisão d i .
Ao fazer isso, ele entra no estado decidido, no qual não
54
Um pouco de formalismo
Conjunto de nós
– Falhas por fail-stop ou bizantinas
– Mais tarde: fail-stop + recuperação
Objetivo: todos os processos p
ipõem o mesmo valor
em uma variável d
i– Não queremos amarrar de onde vem vi
– vi pode ser proposto por um nó ou decidido a partir de várias propostas
55
Um pouco de formalismo
1 P 2 P3 (crashes) P1Consensus alg ori thm v1=proceed
v3=abort
v2=proceed d1:=proceed d2:=proceed
56
Um pouco de formalismo
Requisitos:
1. Concordância: Todos os nós escolhem o mesmo valor para di
2. Validade: O valor escolhido deve ter sido proposto por algum nó
3. Terminação: Alguma hora, todos decidem um valor
Pode ser descrito de formas ligeiramente diferentes: generais bizantinos, consistência interativa, atomic broadcast, ...
57
Consenso
Consenso com líder (generais bizantinos)
58
Uma boa nova
Esses problemas são equivalentes
– Resolvemos um, resolvemos todos
Por exemplo:
– CI a partir de GB: GB várias vezes, cada processo é líder uma vez
– C de CI: roda CI, depois nós aplicam mesma função a vetor para decidir
59
Uma péssima nova
Nenhum desses consensos pode ser garantido em um sistema
assíncrono com falha
– Não podemos decidir não levar em conta a opinião de um nó; ele pode estar apenas lento e mandar a mensagem na hora errada
Consenso pode acontecer frequentemente ou pode acontecer raramente
60
Mas a vida continua
Se consenso não funciona em um sistema assíncrono e:
– Multicast totalmente ordenado?
– Replicação consistente?
– Commits em grupo?
Na prática, vivemos com isso:
– Tentamos até que o sistema se comporte como síncrono
– Mascaramos falhas: esperamos até o processo responder
– Usamos detectores de falha:
61
Comentário
Eleição é um consenso
Casos de falha, não há acordo sobre quem é líder
– Qualquer um pode achar que é
– Se gente demais achar que é, há um livelock
Como um líder não bagunça trabalho do outro?
– Propostas são ordenadas
Questões
Vinícius Fernandes Soares Mota Sincronização