MIT 6.824 Aula 6: Raft e Tolerância a Falhas, Parte 1
Tradução automática para o português do Brasil. Gerada e salva em 2026-10-23. Pode conter erros; confira os termos e as citações na versão em inglês e no vídeo original. Os horários são os mesmos da fonte. A transcrição original em inglês está disponível abaixo.
MIT 6.824 sobre Raft, parte 1: por que sistemas anteriores dependem de um único mestre, como a votação por maioria evita o cérebro dividido, e como termos, eleições e o log funcionam.
Fonte da transcrição: reconhecimento automático de fala no Vidleaf (pode conter erros). Pontuação por IA adicionada pelo Vidleaf; redação original e âncoras de timestamp mantidas. A transcrição original está disponível abaixo.
Pesquise esta transcrição na bancada de trabalhoLeia a transcrição
Resumo gerado por IA
Esta aula introduz o Raft e o padrão de mestre único, em parte para apoiar os laboratórios e como um estudo de caso em replicação de máquina de estados correta. Observa que MapReduce, GFS e VMware FT dependem todos de uma única entidade para decidir o primário, que não pode discordar de si mesma, mas é ela própria um ponto único de falha, então o problema central é evitar o cérebro dividido. Um servidor test-and-set replicado mostra a dificuldade: exigir que o cliente fale com ambas as réplicas não é tolerante a falhas, enquanto falar com apenas uma permite que uma partição de rede produza dois clientes que ambos acreditam deter o bloqueio. O failover automatizado, em vez disso, usa votação por maioria, onde o progresso requer uma maioria de todos os servidores, de modo que no máximo uma partição pode progredir, e com 2f+1 servidores o sistema tolera f falhas; a sobreposição de maiorias é uma grande parte do porquê o Raft está correto. A aula credita o Paxos e a replicação por view stamp (VSR) como sistemas de consenso iniciais, observa que o design do Raft é mais próximo do VSR, e descreve o Raft como uma biblioteca incluída em uma aplicação de serviço, com código de aplicação acima de uma camada Raft que mantém um log, três réplicas de estrutura idêntica, e clientes externos enviando requisições como put e get para a camada de aplicação do líder atual. Em seguida, explica como uma requisição é replicada até que uma maioria das réplicas a tenha em seus logs, após o que o líder a executa e responde, com o líder incluindo o índice de commit no próximo RPC de append entries; cobre por que o Raft mantém logs, a lacuna de controle de fluxo, recuperação de falhas, a interface do canal de aplicação, eleição de líder com números de termo e no máximo um líder por termo, votos divididos e randomização de temporizador, e casos extremos em que líderes falham em momentos estranhos, incluindo que uma entrada que pode não ter sido confirmada deve ser tratada como confirmada.
Gerado a partir da transcrição. Verifique as passagens vinculadas em relação ao vídeo original.
Resumos de capítulos com carimbos de tempo
Raft e o Padrão de Mestre Único
- [0:07] Raft é o tópico para hoje e amanhã, em parte para ajudar na implementação dos laboratórios e como um estudo de caso em acertar a replicação de máquina de estados.
- [0:25] Os sistemas de tolerância a falhas vistos até agora compartilham um padrão: o MapReduce replica a computação, mas toda a computação é controlada por um único mestre.
- [0:49] O GFS replica dados por meio de um esquema de backup primário, mas depende de um único mestre para escolher o primário para cada pedaço de dados.
- [1:06] O VMware FT replica a computação em uma máquina virtual primária e de backup, mas depende de um único servidor test-and-set para garantir que exatamente uma assuma em caso de falha.
- [1:27] Em todos os três casos, uma única entidade fica escondida em um canto para tomar a decisão crítica de quem é o primário.
- [1:46] A vantagem de uma única entidade decidir o primário é que ela não pode discordar de si mesma, mas a desvantagem é que ela própria é um ponto único de falha.
- [2:23] O ponto principal é como evitar o cérebro dividido, e é por isso que decidir quem deve ser o primário após uma falha exige extremo cuidado.
Cérebro dividido em test-and-set replicado
- [2:50] Um servidor test-and-set replicado é usado como ilustração de por que o cérebro dividido é difícil de acertar, motivado pelo VMware FT depender de um servidor test-and-set para escolher o primário.
- [3:34] Ambas as réplicas começam com estado zero, e a única operação do cliente é test-and-set, que define ambas as cópias como um e retorna o valor antigo, atuando como um servidor de lock simplificado.
- [4:04] O split brain surge quando um cliente consegue falar com um servidor mas não com o outro, então o sistema precisa decidir como reagir quando um servidor parece não responder.
- [4:47] Exigir que o cliente fale com ambas as réplicas para qualquer operação evita inconsistência, mas não é tolerante a falhas de forma alguma, já que ambos os servidores precisam estar ativos.
- [5:53] Deixar o cliente falar apenas com o servidor que ele consegue alcançar também está errado, porque o servidor inalcançável pode na verdade estar ativo devido a um problema de rede.
- [6:19] Se um cabo de rede rompido corta a rede ao meio, o cliente um consegue alcançar o servidor um mas não o servidor dois, enquanto outro cliente consegue alcançar o servidor dois mas não o servidor um.
- [6:49] Sob a regra de falar com um só, o test-and-set do cliente um define o servidor um como um e retorna zero, então o cliente um pensa que obteve o lock e que aquele servidor poderia ser o primário do VMware FT, enquanto a outra réplica ainda mantém zero.
- [7:07] O cliente dois então também adquire o lock via servidor dois, então ambas as máquinas VMware poderiam se considerar primárias sem consultar o outro servidor, uma falha completa.
Trade-off de dois servidores e split-brain
Replicação inicial e como evitar o split brain
- [8:15] Operadores de centrais telefônicas e de computadores bancários estavam dispostos a gastar pesado em sistemas replicados para um serviço confiável.
- [8:34] Eles usaram algumas técnicas para ter replicação enquanto tentavam descartar o split brain.
- [8:40] Uma técnica era construir uma rede que não pudesse falhar, como os fios dentro de um notebook conectando a CPU à DRAM.
- [9:03] Com premissas razoáveis, muito dinheiro e uma configuração física cuidadosamente controlada, uma rede que não pode falhar consegue descartar o split-brain.
- [9:24] Se a rede não pode falhar, um cliente incapaz de falar com o servidor dois implica que o servidor dois deve estar fora do ar.
- [9:42] Outra possibilidade era ter seres humanos resolvendo o problema, com os clientes por padrão esperando ambas as réplicas responderem.
- [9:57] Uma pessoa poderia ser acionada por pager até a sala de máquinas para desligar uma réplica ou verificar que uma caiu e a outra está ativa, atuando como desempate.
- [10:24] As pessoas usaram um ou outro desses esquemas por muito tempo; humanos não respondem muito rápido e a rede à prova de falhas é cara, mas viável.
Votação por maioria e sistemas de quórum
- [10:41] Sistemas automatizados de failover podem funcionar corretamente diante de redes instáveis que podem falhar e se particionar.
- [11:03] A ideia-chave para construir sistemas de replicação automatizados que evitam o split-brain é a ideia de voto por maioria.
- [11:29] O primeiro passo é usar um número ímpar de servidores, já que uma divisão par é simétrica demais e ambos os lados fariam a mesma coisa.
- [12:06] No Raft, fazer qualquer progresso (eleger um líder ou confirmar uma entrada de log) exige reunir uma maioria de mais da metade de todos os servidores.
- [12:41] Isso funciona porque no máximo uma partição pode conter uma maioria dos servidores, então a outra partição não consegue fazer progresso.
- [13:08] Uma maioria é sempre contada em relação a todos os servidores, não apenas aos servidores ativos.
- [13:53] Com 2f+1 servidores, o sistema consegue suportar f falhas; três servidores toleram uma falha.
- [14:20] Esses são frequentemente chamados de sistemas de quórum, já que a maioria necessária às vezes é chamada de quórum.
- [15:04] Quaisquer duas maiorias se sobrepõem em pelo menos um servidor, e o Raft depende dessa sobreposição para evitar o split-brain.
A sobreposição de maiorias garante a correção do Wrapped
- [15:50] Qualquer coisa que o líder anterior possa ter confirmado deve estar presente em uma maioria dos servidores no Wrapped.
- [15:54] A maioria de qualquer novo líder deve se sobrepor a pelo menos um servidor que detém cada entrada confirmada do líder anterior.
- [16:05] Essa sobreposição de maiorias é uma grande parte do motivo pelo qual o Wrapped está correto.
- [16:14] O palestrante então convida perguntas sobre o conceito geral de sistemas de votação por maioria.
Adicionar servidores e sistemas de consenso iniciais
- [16:30] É possível adicionar ou alterar o conjunto de servidores, abordado talvez na seção seis.
- [16:43] Sistemas de longa duração precisam de substituição de servidores depois de um tempo devido a falha permanente, atualizações ou mudança de sala de máquinas.
- [17:00] Alterar conjuntos de servidores não acontece todo dia, mas é crítico para a manutenibilidade de longo prazo.
- [17:07] Os autores do Raft se atribuem um esquema que lida com isso, que é complexo.
- [17:21] Por volta de 1990, dois sistemas foram propostos que usavam votação por maioria com três servidores em vez de dois para contornar o split brain.
- [17:45] Um sistema inicial era chamado de Paxos, que o artigo do Raft discute bastante.
- [17:53] Outro sistema inicial era a replicação por view stamp (VSR), inventada por pessoas do MIT; o design do Raft é mais próximo do VSR do que do Paxos.
- [18:16] Esses sistemas têm uma história de muitas décadas, mas só vieram à tona em grandes sistemas distribuídos implantados há cerca de 15 anos.
Raft como biblioteca
Arquitetura de serviço replicado com Raft
- [18:50] Um serviço replicado consiste em código de aplicação que recebe RPCs mais uma biblioteca Raft, e as bibliotecas Raft cooperam para manter a replicação.
- [19:11] Uma única réplica Raft tem o código de aplicação no topo (por exemplo, um servidor de chave-valor) com estado replicado que o Raft ajuda a gerenciar, como uma tabela de chaves e valores.
- [19:38] Abaixo da aplicação está a camada Raft; o servidor de chave-valor faz chamadas de função para o Raft, e o Raft mantém estado, mais criticamente um log de operações.
- [20:06] Em um sistema com três réplicas, há três servidores com estrutura idêntica e, esperançosamente, os mesmos dados em ambas as camadas.
- [20:33] Os clientes são código externo que envia requisições para a camada de aplicação do líder atual, e a esperança é que os clientes não precisem saber que estão falando com um serviço replicado.
- [21:13] Requisições no nível da aplicação para um servidor de chave-valor podem ser put (recebe uma chave e um valor e atualiza a tabela) e get (retorna o valor atual de uma chave).
- [21:55] Em um serviço replicado pelo Raft, a camada de aplicação não executa a requisição; ela envia a requisição do cliente para baixo, para a camada Raft, para que seja confirmada no log replicado.
- [22:16] O Raft replica a operação até que uma maioria das réplicas a tenha em seus logs, então notifica o líder, que então executa a operação e responde ao cliente.
- [23:36] A confirmação exige uma maioria em vez de todas as réplicas para que o sistema tolerante a falhas possa fazer progresso mesmo se alguns servidores tiverem falhado.
- [24:10] Quando uma operação é confirmada, a biblioteca Raft de cada réplica a envia para cima, para a camada de aplicação local, que a aplica ao seu estado, de modo que todas as réplicas vejam o mesmo fluxo de operações.
Operação normal do Raft e propagação da confirmação
- [24:33] Operações determinísticas aplicadas na mesma ordem fazem o estado replicado evoluir de forma idêntica em todas as réplicas.
- [25:09] Um diagrama de tempo mostra o cliente enviando uma requisição ao líder (servidor um), que envia RPCs de append entries para as duas réplicas.
- [25:55] O líder espera por respostas positivas de uma maioria, incluindo ele mesmo; com três réplicas, ele só precisa de mais uma réplica.
- [26:14] Depois de reunir uma maioria, o líder executa o comando e envia a resposta de volta ao cliente.
- [27:04] O servidor dois não sabe que a requisição foi confirmada, já que sua resposta pode ter sido descartada pela rede.
- [27:26] Assim que o líder sabe que uma requisição foi confirmada, ele precisa avisar as outras réplicas; no Raft isso é carregado junto no próximo RPC de append entries por meio de um campo de commit do líder, em vez de uma mensagem de commit explícita.
- [29:14] O implementador decide quando o líder envia o índice de commit atualizado: heartbeats ou append entries especiais se as requisições forem raras, carregamento junto se as requisições forem frequentes.
- [29:56] O momento em que as réplicas executam a requisição não é crítico porque ninguém está esperando por isso, pelo menos se não houver falhas.
A execução nas réplicas não está no caminho crítico
Por que o Raft mantém logs e sua lacuna de controle de fluxo
- [30:43] Pergunte explicitamente por que o sistema é tão focado em logs e o que os logs estão fazendo.
- [31:03] O log é o mecanismo pelo qual o líder ordena as operações, o que é vital para máquinas de estado replicadas.
- [31:07] As réplicas devem aplicar não apenas as mesmas operações de cliente, mas as mesmas operações na mesma ordem.
- [31:41] Slots numerados no log fazem parte de como o líder expressa a ordem que escolheu.
- [32:06] Nos seguidores, o log é onde as operações que ainda não se sabe estarem confirmadas são separadas, e elas podem ter que ser descartadas.
- [32:32] O líder mantém as operações em seu log porque pode precisar retransmiti-las para seguidores que perderam mensagens.
- [33:28] Um servidor reiniciado reproduz o log persistido em disco para reconstruir seu estado no momento em que caiu, então o log faz parte do plano de persistência.
- [34:41] Os seguidores confirmam comandos antes de executá-los, então sua taxa de confirmação não é limitada pela taxa de execução.
- [34:56] Se os seguidores confirmarem mais rápido do que executam, eles acumulam logs sem limite e eventualmente ficarão sem memória.
- [35:26] O Raft não tem o controle de fluxo necessário para lidar com isso.
- [35:44] Um sistema de produção pode precisar de uma mensagem extra relatando o progresso da execução para que o líder possa ser limitado se ficar muito à frente.
Recuperação de falhas e confirmação de log no Raft
- [36:37] Um servidor que caiu persistiu seu log em disco, segundo uma das regras da Figura 2.
- [36:46] Após reiniciar, o servidor não sabe até onde chegou na execução do log.
- [36:54] Pelas regras da Figura 2, no primeiro reinício ele nem sabe quanto do log está confirmado.
- [37:03] Imediatamente após reiniciar e ler o log, o servidor não tem permissão para fazer nada com o log porque não sabe até onde o sistema confirmou.
- [37:36] Se todos os servidores caírem, tudo o que eles têm é o estado marcado como não volátil na Figura 2, que inclui o log e talvez o termo mais recente.
- [37:56] Eles executam a eleição de líder, um é escolhido como líder, e o líder descobre o estado como subproduto do envio do primeiro heartbeat.
Ponto de commit do líder e replicação de log
- [38:26] Uma maioria das réplicas concordando com seu log é o ponto de commit.
- [38:33] Uma vez que um líder é escolhido por meio do mecanismo de append entries, ele força todas as outras réplicas a terem logs idênticos ao seu.
- [38:45] Como o líder sabe que todas as réplicas têm logs idênticos ao dele, uma maioria deve conter essas entradas, então elas também devem estar confirmadas.
- [39:13] O código de append entries do líder na figura dois incrementa o ponto de commit do líder.
- [39:18] Todos podem então executar o log inteiro desde o início e recriar seu estado do zero, possivelmente de forma extremamente trabalhosa.
- [39:30] Reexecutar do zero não é muito atraente, mas é o que o protocolo básico faz.
Versão Eficiente e Prévia da Interface
Interface entre a camada de chave-valor e o Raft
- [40:14] Em cada réplica há duas peças principais da interface entre a camada de chave-valor e a camada Raft.
- [40:22] A camada de chave-valor repassa as requisições do cliente ao Raft por meio da função start, pedindo que ele encaixe a requisição no log.
- [40:36] A função start em raft.go recebe um argumento, o comando do cliente, e informa à camada de chave-valor quando ele é confirmado.
- [40:53] O Raft notifica a camada de chave-valor que uma operação enviada anteriormente em um comando start foi confirmada, o que pode não ser o start mais recente.
- [41:02] Cem comandos de clientes podem chegar e causar chamadas a start antes que qualquer um deles seja confirmado.
- [41:13] A comunicação ascendente assume a forma de uma mensagem em um canal Go no qual a biblioteca Raft envia e a camada de chave-valor lê.
- [41:27] O canal apply transporta mensagens de apply, e a camada de chave-valor deve correlacioná-las com suas chamadas a start.
- [41:48] O comando start retorna o índice no log onde o comando será confirmado, se for confirmado, o que pode não acontecer, além do termo atual.
- [42:13] A mensagem de apply contém o comando e o índice, e todas as réplicas a recebem e aplicam o comando ao seu estado local.
- [42:36] O índice só é realmente útil no líder, para que ele possa descobrir de quais requisições de clientes se está falando.
Momento da resposta ao cliente em RPC de chave-valor replicado
- [43:14] O cliente envia uma requisição (put ou get) e espera por uma resposta.
- [43:31] O líder só envia uma resposta depois de saber que o comando foi confirmado.
- [43:55] Na pilha de software, a camada de chave-valor chama a função start, que retorna à camada de chave-valor.
- [44:05] A camada de chave-valor ainda não responde ao cliente porque não sabe se a requisição será confirmada.
- [44:18] A requisição pode não ser confirmada se a camada de chave-valor falhar imediatamente após o retorno de start, antes de enviar mensagens de apply.
- [44:38] O servidor de chave-valor executa a requisição somente quando a mensagem de apply correspondente aparece no canal apply, e então envia uma resposta.
- [45:01] Isso importa principalmente sob falha: quando ocorrem falhas, o que o cliente viu torna-se extremamente importante.
Divergência e Convergência do Log no Raft
- [45:22] Inicialmente, os logs de diferentes réplicas podem não ser idênticos.
- [45:30] Os logs das réplicas podem divergir por breves períodos em várias situações.
- [45:40] Um exemplo: um líder envia uma rodada de mensagens de append mas falha antes de enviar todas.
- [45:45] As réplicas que receberam a mensagem de append anexam a nova entrada de log, enquanto as que não receberam o RPC não o fazem.
- [46:01] O Raft eventualmente força os logs a se tornarem idênticos, apesar das diferenças transitórias.
- [46:11] O líder modifica os logs até garantir que todos sejam idênticos.
Noções básicas de eleição de líder no Raft
- [46:27] O Raft tem dois grandes tópicos: eleição de líder (Lab 2) e como o líder lida com os logs das réplicas, especialmente após falhas.
- [46:50] Um líder não é estritamente necessário; um cluster sem líder pode concordar com uma sequência de log, e o Paxos original não tinha líder.
- [47:17] O Raft usa um líder principalmente para eficiência no caso comum em que os servidores não falham, permitindo acordo em uma rodada de mensagens por requisição.
- [47:49] Usar um líder provavelmente acelera o sistema por um fator de dois e torna mais fácil raciocinar sobre ele.
- [48:07] O Raft usa números de termo para desambiguar líderes; os seguidores precisam apenas do número do termo atual, não da identidade do líder.
- [48:20] Propriedade crítica: cada termo tem no máximo um líder—pode não haver nenhum, mas nunca dois no mesmo termo.
- [48:45] Cada servidor mantém um temporizador de eleição; se ele expirar sem ouvir do líder atual, o servidor assume que o líder está morto e inicia uma eleição.
- [49:31] Iniciar uma eleição significa incrementar o termo e enviar RPCs de solicitação de voto, com o candidato votando em si mesmo (n-1 requisições).
- [50:16] Eleições podem ocorrer mesmo sem falha do líder, por exemplo, rede lenta ou heartbeats perdidos, então a correção deve levar isso em conta.
- [50:46] Após uma nova eleição, o líder antigo pode ainda pensar que é líder, por exemplo, em uma partição minoritária, então seu comportamento deve ser tratado.
Falhas de rede unidirecionais no Raft
- [51:53] Casos patológicos em que a comunicação de rede unidirecional impede o progresso são possíveis.
- [51:55] Se os heartbeats de saída do líder funcionam, mas ele não consegue receber requisições de clientes, seus heartbeats impedem que outros servidores iniciem uma eleição.
- [52:20] A rede de entrada quebrada impede o líder de ouvir e executar comandos de clientes.
- [52:28] O Raft não é à prova de todos os problemas malucos de rede que podem surgir.
- [52:37] O palestrante acredita que os casos que ele considerou são corrigíveis.
- [52:45] Uma correção é exigir um heartbeat bidirecional, em que os seguidores respondem aos heartbeats.
- [52:58] Se o líder parar de ver respostas de heartbeat, após algum tempo ele decide renunciar.
Eleição de líder por regra de maioria no Raft
- [53:32] O Raft deve garantir no máximo um líder por termo.
- [53:38] Para ser eleito para um termo, um candidato precisa de votos 'sim' de uma maioria dos servidores.
- [53:45] Cada servidor dá apenas um voto 'sim' por termo, então dois candidatos não podem ambos obter maioria.
- [54:08] A regra de maioria resulta em no máximo um candidato vencedor por termo.
- [54:26] A regra de maioria significa que um líder pode ser eleito mesmo se uma minoria dos servidores tiver falhado ou estiver indisponível.
- [54:34] Se mais da metade tiver falhado, estiver indisponível ou estiver em outra partição, o sistema continua tentando e nunca elege um líder.
- [54:54] Se uma eleição for bem-sucedida, seria ótimo se todos soubessem disso.
Como os servidores Raft descobrem os resultados da eleição
- [55:00] Todas as partes precisam de uma maneira de saber o que aconteceu em uma eleição.
- [55:16] O candidato vencedor sabe diretamente que obteve maioria dos votos, mas ninguém mais sabe diretamente quem venceu ou se alguém venceu.
- [55:28] O candidato informa os outros servidores por meio de AppendEntries de heartbeat, que a Figura 2 exige imediatamente após vencer uma eleição.
- [55:41] O heartbeat não diz explicitamente quem venceu ou qual termo; o sinal é sutil.
- [55:56] Apenas um líder de um termo pode enviar AppendEntries, então receber AppendEntries para o termo 19 informa a um servidor que alguém venceu aquela eleição, embora não quem.
- [56:21] AppendEntries também reinicia o temporizador de eleição de todos, suprimindo novas candidaturas enquanto o líder enviar heartbeats na taxa esperada.
- [56:51] Se a rede falhar ou pacotes forem descartados, uma eleição pode ocorrer mesmo assim, mas se tudo correr bem é improvável que ocorra uma eleição.
- [57:03] O esquema não pode eleger dois líderes para um termo, mas pode eleger zero líderes para um termo, principalmente se muitos servidores estiverem mortos, indisponíveis ou com conexões de rede ruins, de modo que uma maioria não possa ser formada.
Timeouts de eleição e votos divididos no Raft
- [57:23] Uma eleição pode falhar mesmo sem perda de pacotes se dois ou mais candidatos expirarem quase juntos e dividirem o voto.
- [57:44] Em um sistema de três réplicas em que todos os temporizadores de eleição disparam simultaneamente, cada servidor vota em si mesmo e ninguém obtém maioria.
- [58:09] Como os temporizadores de eleição só são reiniciados por um append entries, sem líder eles disparam novamente e podem dividir o voto repetidamente.
- [58:31] O Raft torna os votos divididos improváveis, mas não impossíveis, randomizando os temporizadores de eleição.
- [59:43] Se os servidores escolherem tempos aleatórios diferentes, um temporizador dispara primeiro e, se a diferença for grande o suficiente, ele pode enviar uma rodada completa de solicitações de voto antes que o próximo temporizador dispare.
- [1:00:23] A randomização dessincroniza os candidatos.
- [1:00:41] O temporizador de eleição deve ser pelo menos tão longo quanto o intervalo esperado de heartbeat; com possíveis perdas de pacotes, o mínimo deve ser algumas vezes o intervalo de heartbeat, por exemplo, 300 ms para heartbeats de 100 ms.
- [1:02:00] O timeout aleatório máximo afeta a rapidez com que o sistema se recupera de uma falha, já que o sistema fica congelado sem líder até que o primeiro temporizador de eleição dispare.
Ajuste e randomização do timeout de eleição
- [1:02:36] O nível de desempenho necessário e a frequência esperada de falhas determinam o quanto as configurações de timeout importam.
- [1:02:43] Se as falhas acontecem apenas uma vez por ano, elas podem não importar muito; falhas frequentes fazem com que importem muito.
- [1:02:50] O tempo de recuperação também é uma consideração.
- [1:03:04] A diferença entre o disparo do primeiro e do segundo temporizador deve ser maior que o tempo para um candidato reunir votos de todos.
- [1:03:12] Essa diferença deve exceder o tempo de ida e volta esperado para um RPC, que pode ser cerca de 10 milissegundos.
- [1:03:25] O timeout máximo deve ser longo o suficiente para que uma diferença de 10 milissegundos entre o menor e o segundo menor número aleatório seja bastante provável.
- [1:03:53] O código de teste ficará insatisfeito se uma falha de líder não for recuperada em alguns segundos, então o máximo deve ser ajustado para baixo para que a eleição de líder tenha alta probabilidade de ser concluída em poucos segundos.
- [1:04:20] Um novo timeout aleatório deve ser escolhido sempre que o temporizador de eleição for reiniciado, em vez de reutilizar um escolhido na criação do servidor.
- [1:04:39] Reutilizar o mesmo número aleatório arrisca que dois servidores escolham o mesmo valor e causem votos divididos repetidamente para sempre.
Líder antigo em partição minoritária
- [1:05:02] Última questão de eleição de líder: o líder antigo está particionado com uma minoria de servidores e alguns clientes, enquanto a maioria elege um novo líder.
- [1:06:08] Um não-problema: um líder em outra partição sem maioria envia append entries mas não consegue respostas de uma maioria, então nunca confirma ou executa a operação.
- [1:06:47] Os clientes podem enviar requisições ao servidor antigo mas nunca receber respostas, então nenhum cliente é enganado a pensar que executou algo.
- [1:07:00] Uma questão mais complicada: um servidor pode enviar append entries para um subconjunto de servidores e então falhar antes de tomar uma decisão de confirmação.
- [1:07:24] Essa questão provavelmente levará cerca de 45 minutos para ser discutida.
Divergência de log após falha do líder
- [1:07:47] Um líder recém-eleito pode precisar reconciliar logs divergentes entre réplicas para restaurar um estado consistente após a falha do líder anterior.
- [1:08:16] O tópico é principalmente interessante após a falha de um servidor; enquanto um servidor está ativo com uma maioria, os seguidores devem aceitar o log do líder e pouco pode dar errado.
- [1:08:50] Problemas surgem quando o líder antigo falha no meio do envio de mensagens, ou um novo líder falha logo após a eleição antes de fazer algo útil.
- [1:09:48] Nos diagramas, as entradas de log são escritas como números de termo em vez de operações de cliente, alinhadas por slot.
- [1:10:03] No exemplo, todos os três servidores têm uma entrada de termo três no slot um, mas apenas os servidores 2 e 3 têm uma entrada de termo três no slot dois, enquanto o servidor 1 não tem nada lá.
- [1:11:03] Isso pode ocorrer se o servidor 3 era líder no termo três, enviou um comando para todos, então recebeu uma segunda requisição e a enviou para todos os três, mas a mensagem para o servidor 1 foi perdida ou o servidor 1 estava inativo.
- [1:11:53] Se o servidor 3 falhar e outro líder for escolhido, o novo líder não deve descartar um comando possivelmente confirmado e deve fazer o servidor 1 preencher a lacuna com o mesmo comando que os outros tinham.
Viabilidade da configuração do log do Raft
- [1:12:28] Uma nova eleição de líder pode ocorrer porque uma falha aconteceu antes de a mensagem ser enviada.
- [1:12:43] Os espaços no log são numerados 10, 11, 12, 13 para se referir a eles.
- [1:13:03] No espaço 12, o Servidor 2 tem um comando do termo quatro e o Servidor 3 tem um comando do termo cinco.
- [1:13:17] Antes de analisar o que um servidor faria, é preciso perguntar se a configuração poderia sequer ocorrer.
- [1:13:25] Às vezes a resposta é que a configuração não pode surgir, então não é preciso se preocupar com ela.
- [1:15:00] Esta configuração pode surgir: se o Servidor 2 for eleito líder para o termo quatro, anexar uma solicitação de cliente e falhar.
- [1:15:25] O Servidor 3 poderia então ser eleito para o termo cinco porque só precisa de respostas de solicitação de voto de uma maioria, ou seja, o Servidor 1 e o Servidor 3, cujos logs não conflitam.
- [1:15:41] O Servidor 3 então recebe uma solicitação de cliente, anexa-a ao seu log e falha, produzindo esta configuração.
- [1:16:03] É necessário trabalhar nesses cenários para determinar se o Raft deve lidar com eles ou se eles não podem acontecer.
Resultados aceitáveis do Raft
- [1:16:26] Queremos nos convencer de que o Raft faz algo sensato.
- [1:16:42] Antes de discutir o que o Raft faria, precisamos ter uma noção do que seria um resultado aceitável.
- [1:16:53] O comando no espaço 10 é conhecido por todas as réplicas, então poderia ter sido confirmado e não pode ser descartado.
- [1:17:01] O comando no espaço 11 está em uma maioria de réplicas, então poderia ter sido confirmado e não pode ser descartado.
- [1:17:09] O comando no espaço 12 não poderia ter sido confirmado de forma alguma, então o Raft tem o direito de descartar ambos.
- [1:17:27] Descartar qualquer um dos comandos do espaço 12 é um descarte permitido, não obrigatório.
Incerteza de confirmação do log do Raft
- [1:17:31] Pelo menos uma entrada de log deve ser descartada porque o conteúdo final do log deve ser idêntico.
- [1:17:47] Apenas os logs não podem revelar exatamente até onde o líder chegou antes de falhar.
- [1:17:58] Uma possibilidade é que o líder tenha enviado mensagens de anexação com um novo comando e falhado imediatamente, nunca recebendo uma resposta.
- [1:18:13] Sem uma resposta, o líder não executou o comando e não enviou o índice de confirmação incrementado, então as réplicas podem não tê-lo executado também.
- [1:18:28] É possível que a entrada não tenha sido confirmada, mas o Raft não pode provar que não foi, então deve tratá-la como confirmada.
- [1:18:57] O líder pode ter recebido respostas de anexação de entrada e respondido ao cliente antes de falhar, então a entrada não pode ser descartada como confirmada.
- [1:19:07] Olhando os logs, nenhuma das possibilidades pode ser descartada, então a entrada deve ser assumida como confirmada.
Breve indicação de continuação
[0:01] Tudo bem, vamos começar. Mm-hmm. Hoje, e de fato hoje e amanhã, vou falar sobre o Raft. Hum, tanto porque espero que seja útil para vocês na implementação dos laboratórios. E também porque, você sabe, é apenas um estudo de caso nos detalhes de como fazer a replicação de máquina de estados corretamente. Então, como introdução ao problema, vocês podem ter notado um padrão nos sistemas de tolerância a falhas que examinamos até agora.
[0:35] Hum, Um é que o MapReduce replica a computação, mas A replicação é controlada, toda a computação é controlada por um único mestre. Hum, Outro exemplo que gostaria de chamar a atenção é que o GFS replica dados, certo, como esse esquema de backup primário para replicar o conteúdo real dos arquivos, mas Ele depende de um único mestre. para escolher quem é o primário para cada pedaço de dados. Outro exemplo, o VMware FT replica a computação, certo, em uma máquina virtual primária e uma máquina virtual de backup. Mas para descobrir o que fazer em seguida, se uma delas parece falhar, ele depende de um único servidor de teste e configuração.
[1:20] para ajudá-lo a escolher, para ajudá-lo a garantir que exatamente um dos primários ou do backup assuma se houver algum tipo de falha. Então, em todos esses três casos, Claro, havia um sistema de replicação, mas meio escondido em um canto no sistema de replicação, havia algum esquema em que uma única entidade era necessária para tomar uma decisão crítica sobre. quem era o primário nos casos que nos importam. Então, vou começar com o primeiro. uma coisa muito boa sobre ter uma única entidade decidir quem será o primário?
[1:52] é que ela não pode discordar de si mesma. Há apenas uma dela, toma alguma decisão, essa é a decisão que ela tomou. Hum, Mas a coisa ruim sobre ter uma única entidade decidir, tipo, quem é o primário, é que ela própria é um ponto único de falha. E então vocês podem ver esses sistemas que examinamos como que... empurrando o verdadeiro coração da maquinaria de tolerância a falhas para um cantinho. Ou seja, a única entidade que decide quem será o primário. se houver uma falha. Agora, Tudo isso é sobre como evitar o cérebro dividido. A razão pela qual temos que ter, ter que ser extremamente cuidadosos ao tomar a decisão sobre quem deve ser o primário, se houver uma falha, é que caso contrário corremos o risco de cérebro dividido.
[2:35] Hum, E só... deixar esse ponto super claro, vou apenas lembrá-los. qual é o problema e por que é um problema sério. Então, suponhamos, por exemplo, que nós, Hum, Queremos construir um servidor de teste e configuração replicado. Ou seja, estamos preocupados com o fato de que o VMware FT depende desse servidor de teste e configuração para-- escolher quem é o primário, então vamos construir um servidor de teste e configuração replicado. E vou fazer isso, vai ser quebrado, é apenas uma ilustração de por que é difícil acertar o problema do cérebro dividido. Então, vocês sabem, vamos imaginar que temos uma rede, e talvez dois servidores, que deveriam ser réplicas do nosso serviço de Teste e configuração conectados e, você sabe, talvez dois clientes que precisam saber quem é o primário agora? ou na verdade, talvez esses clientes neste caso sejam um O primário e o backup.
[3:30] hum, no VMware FT. Então, Se é um serviço de teste e configuração, então ambos esses bancos de dados, ambos esses servidores começam com seu estado, ou seja, o estado deste teste e configuração sendo zero. a única operação que seus clientes podem enviar é a operação de teste e configuração que deveria definir o do serviço replicado para um, então deveria definir ambas as cópias. e então retornar o valor antigo. Então ele essencialmente age como um tipo de servidor de bloqueio simplificado. Hum, Obrigado.
[4:01] OK. A situação problema? O que nos preocupa, o cérebro dividido surge automaticamente. quando um cliente pode falar com um dos servidores mas não pode falar com o outro. Então estamos imaginando que quando os clientes enviam uma solicitação, eles a enviam para ambos. Hum, vou apenas assumir isso agora, quase não importa. Então vamos assumir que o protocolo é que o cliente deve enviar ordinariamente qualquer solicitação para ambos os servidores, E De alguma forma, precisamos pensar sobre o que o cliente deve fazer se um dos servidores não responder.
[4:32] ou o que o sistema deve fazer se um dos servidores parecer não responder. Hum, Obrigado. Então vamos imaginar agora que o cliente um pode contatar o servidor um mas não o servidor dois. Como o sistema deve reagir? Uma possibilidade é que pensemos, bem, você sabe, caramba, Certamente não queremos apenas falar com o cliente para o servidor um, porque isso deixaria a segunda réplica inconsistente se definíssemos este valor para um, mas não definíssemos também este valor para um. Então talvez a regra deva ser que um cliente sempre precise falar com ambas as réplicas. para ambos os servidores. para qualquer operação e não deveria ser permitido falar apenas com um deles.
[5:05] Então por que essa é a resposta errada? Suponhamos que a regra seja, oh, em nosso sistema replicado, o cliente sempre precisa Falar com ambas as réplicas. para fazer progresso. Obrigado. Isso não é tolerante a falhas de jeito nenhum. Na verdade, é pior. É pior. do que falar com um único servidor porque agora o sistema tem um problema se qualquer um desses servidores falhar ou se você não puder falar com ele. Pelo menos com um servidor não replicado, você depende apenas de um servidor. Mas aqui temos que ambos os servidores estejam vivos. Se exigirmos que o cliente fale com ambos os servidores então. Ambos os servidores têm que estar vivos. Então não podemos de forma alguma exigir que o cliente realmente, você sabe, espere que ambos os servidores respondam.
[5:48] Se não temos tolerância a falhas, precisamos que ele possa prosseguir. Então outra resposta óbvia é que, Se o cliente não pode falar com ambos, bem, ele apenas fala com aquele com quem pode falar e conclui que o outro está morto. Então por que isso também não é a resposta certa? O cenário preocupante é se o outro servidor estiver na verdade vivo. Então suponha que o problema real que estamos encontrando não seja que o servidor falhou, o que seria bom para nós, mas o problema muito pior de que algo deu errado com o cabo de rede. E que este cliente pode falar com, o cliente um pode falar com o servidor um mas não com o servidor dois.
[6:27] E talvez haja algum outro cliente por aí que possa falar com o servidor dois mas não com o servidor um. Então, Se fizermos a regra, de que se um cliente não pode falar com ambos os servidores, tudo bem para ser tolerante a falhas, que ele apenas falou com um, então o que-- inevitavelmente vai acontecer. disse, este cabo vai quebrar, assim Cortando a rede ao meio. Vou-- enviar uma solicitação de teste e configuração para o servidor um, O servidor um definirá seu estado para um. Retornará o valor anterior de 0 para o cliente 1. E então isso significa que o cliente 1 pensará que tem o bloqueio.
[7:00] e se for um VMware FT, o servidor pensará que pode ser o primário de assumir. Mas esta réplica ainda tem zero nela. Certo, então agora se o cliente dois também enviar uma solicitação de teste e configuração, para Você sabe, nós-- tenta enviá-las para ambos, vê que o servidor um parece estar inativo, segue a regra que diz, bem, você apenas envia para o servidor com quem pode falar, então ele também pensará que Hum. adquiriu, o cliente dois também pensará que adquiriu o bloqueio. E então agora, Você sabe, se estivéssemos imaginando que este servidor de teste e configuração seria usado com o VMware FT, temos, você sabe, Ambos.
[7:31] uh, réplica, ambas essas máquinas VMware, uh, eu acho que elas poderiam ser primárias por si mesmas. Hum, sem consultar o outro servidor. Então isso é uma falha completa. Então com esta configuração e dois servidores, Parecia que tínhamos isso, nós apenas tínhamos que escolher, ou você espera por ambos e não é tolerante a falhas, ou Você espera por apenas um e não é correto. E a versão não correta é frequentemente chamada de cérebro dividido. Então. Todos veem isso? Obrigado.
[8:03] Mm-mm. Bem. Hum... Então foi basicamente onde as coisas estavam. até o final dos anos 80. E Mas as pessoas queriam construir Sistemas replicados. os computadores que controlam centrais telefônicas, ou os computadores que administravam bancos, você sabe. Esses lugares estão dispostos a gastar uma quantia enorme de dinheiro para ter um serviço confiável, e então eles replicavam, eles construíam sistemas replicados, e a maneira como eles lidavam A maneira como eles-- tinham replicação mas tentavam excluir o cérebro dividido. É um par de técnicas. Uma é Eles construíam uma rede que não podia falhar.
[8:44] E então, geralmente o que isso significa, e de fato vocês usam redes que essencialmente não podem falhar o tempo todo. os fios dentro do seu laptop, você sabe, conectando a CPU à DRAM são efetivamente uma rede que não pode falhar. entre a-- entre sua CPU e a DRAM. Então, você sabe, com suposições razoáveis e muito dinheiro, e aquilo, você sabe, meio que uma situação física cuidadosamente controlada, tipo você não quer ter um cabo serpenteando pelo chão que alguém possa pisar, sabe, tem que ser uma configuração fisicamente bem projetada. Com uma rede que não pode falhar, você pode descartar o cérebro dividido. É meio que uma suposição, mas com dinheiro suficiente as pessoas chegam bem perto disso porque Se a rede não pode falhar, isso basicamente significa que o cliente não consegue falar com o servidor dois, isso significa que o servidor dois deve estar fora do ar.
[9:31] porque não pode ter sido a rede falhando. Então essa foi uma maneira que as pessoas meio que construíram sistemas de replicação que não sofriam de cérebro dividido. Obrigado. Um. Outra possibilidade seria ter alguns seres humanos para resolver o problema, ou seja, não fazer nada automaticamente, em vez disso ter os clientes Por padrão, os clientes sempre têm que esperar, você sabe, ambas as réplicas responderem ou algo assim, nunca me é permitido prosseguir com apenas uma delas. Mas você pode, sabe, acionar o pager de alguém para tocar, algum ser humano vai à sala de máquinas e meio que olha as duas réplicas e, ou desliga uma, para garantir que ela está definitivamente morta.
[10:08] ou verifica que uma delas de fato travou, e que a outra está viva. E então você está essencialmente usando o humano como o desempate, e o humano é um, você sabe. se ele fosse um computador, seria um ponto único de falha ele mesmo. clube. Então, por muito tempo, as pessoas usaram um ou outro desses esquemas para construir sistemas replicados, e não é, você sabe, Eles podem ser feitos para funcionar. Os humanos não respondem muito rapidamente. E a rede que não pode falhar é cara, mas não é não factível. Um, Mas acabou que você pode realmente construir sistemas automatizados de failover Um, que podem funcionar corretamente diante de redes instáveis, de redes que podem falhar.
[10:50] que podem se particionar. Então essa divisão da rede ao meio onde os dois lados operam mas não conseguem falar um com o outro, Isso geralmente é chamado de partição. Um. Obrigado. Obrigado. E o grande insight que as pessoas tiveram para construir sistemas automatizados de replicação que não sofrem de cérebro dividido é a ideia de voto majoritário. E então isto é-- Obrigado. Obrigado. Obrigado. um conceito que aparece tipo em cada outra frase praticamente no artigo do Raft.
[11:24] É meio que uma forma fundamental-- um modo de proceder. O primeiro passo é ter um número ímpar de servidores em vez de um número par de servidores. Tipo, uma falha aqui é que é um pouco simétrico demais. Os dois lados da divisão aqui, eles simplesmente parecem iguais. Eles rodam o mesmo software, eles vão fazer a mesma coisa, e isso não é bom. Mas se você tem um número ímpar de servidores, Então, Não é mais simétrico. Certo. Pelo menos uma única divisão de rede será presumivelmente dois servidores de um lado e um servidor do outro lado, e eles não serão nem um pouco simétricos.
[11:57] E isso é parte do que os esquemas de voto majoritário estão. apelando. Então, ideia básica é você ter um número ímpar de servidores, para fazer progresso de qualquer tipo, então no Raft, eleger um líder, ou fazer com que uma entrada de log seja confirmada, para fazer qualquer progresso em cada etapa, Você tem que reunir uma maioria... dos servidores, mais da metade, mais da metade de todos os servidores, para meio que aprovar aquela etapa, tipo votar em um líder, aceitar uma nova entrada de log e confirmá-la. Um, Então, você sabe, o mais...
[12:29] uh... A maneira direta é ter dois ou três servidores necessários para fazer qualquer coisa. Um, Uma razão pela qual isso funciona, é claro, é que Se houver uma partição, Não pode haver mais de uma partição com uma maioria dos servidores nela. Essa é uma maneira de ver isso. Uma partição pode ter um servidor nela, o que não é uma maioria. Ou talvez você possa ter dois, mas se uma partição tem dois, então a outra partição tem que ter apenas um servidor nela. e portanto nunca será capaz de reunir uma maioria e não conseguirá fazer progresso.
[13:03] Um, E apenas... Para ser totalmente claro, Quando estamos falando de uma maioria, é sempre uma maioria de todos os servidores. não apenas dos servidores vivos. Este é um ponto que me confundiu por muito tempo, Se você tem um sistema com três servidores, e talvez alguns deles tenham falhado ou algo assim, Se você precisa reunir uma maioria, é sempre dois de três. mesmo se você sabe que um falhou. A maioria é sempre do número total de servidores. um, Há uma formulação mais geral disso. Por causa do sistema de voto majoritário em que dois de três são necessários para fazer progresso, ele pode sobreviver à falha de um servidor.
[13:40] Certo. Quaisquer dois servidores são suficientes para fazer progresso. Se você precisa ser capaz de, se você está, sabe, preocupado com quão confiáveis seus servidores são ou Deus. você pode construir sistemas que têm mais servidores, e então a formulação mais geral é Se você tem dois f mais um servidores, então você pode suportar F falhas. Tchau. Então se são três, Isso significa que f é um. Em um sistema com três servidores, você tolera F servidores, F1 falha e continua funcionando.
[14:16] Obrigado. Obrigado. Obrigado. Tudo bem. Frequentemente esses são chamados de sistemas de quórum porque os dois de três às vezes são considerados um quórum. Obrigado. Ok, então uma propriedade que eu já mencionei sobre esses sistemas de voto majoritário é que Um, No máximo uma partição pode ter uma e portanto se a rede estiver particionada, Não podemos ter ambas as metades da rede fazendo progresso. Outra coisa mais sutil acontecendo aqui é que Um, Se você sempre precisa de uma maioria.
[14:49] dos servidores para prosseguir. E você passa por uma espécie de sucessão de operações em que a cada operação alguém reuniu uma maioria tipo. você sabe, votos para líderes ou Digamos votos para líderes no Raft. A cada passo, a maioria que você reúne para aquele passo deve conter pelo menos um servidor que estava na maioria anterior. quaisquer duas maiorias se sobrepõem em pelo menos um servidor. E é realmente essa propriedade, mais do que qualquer outra coisa, que o Raft está usando.
[15:22] Um, para evitar cérebro dividido. É o fato de que, por exemplo, quando você tem um líder, uma eleição de líder bem-sucedida, e um líder reúne votos de uma maioria, sua maioria tem garantia de se sobrepor à maioria do líder anterior. Então, por exemplo, o novo líder tem garantia de saber sobre o número do termo usado pelo líder anterior. porque sua maioria se sobrepõe à maioria do líder anterior e todos na maioria do líder anterior sabiam sobre o número do termo do líder anterior. Similarmente, qualquer coisa que o líder anterior-- poderia ter confirmado deve estar presente em uma maioria dos servidores no Raft, e portanto a maioria de qualquer novo líder deve se sobrepor a pelo menos um servidor.
[16:01] com cada entrada confirmada. do líder anterior. Esta é uma grande parte do Por que é que... O Raft está correto. Alguma pergunta sobre... o conceito geral de sistema de voto majoritário. Sim? Também é comum adicionar servidores? Tipo adicionar o processamento? JONATHAN GRUBER: É possível adicionar servidores? Acho que é possível. É possível, você sabe, seção algo, talvez seis no como adicionar ou mudar o conjunto de servidores.
[16:41] É possível. Você precisa fazer isso em um sistema de longa duração. Se você está rodando seu sistema por cinco, 10 anos, você vai precisar substituir os servidores depois de um tempo. você sabe, um deles falha permanentemente, ou você faz upgrade, ou você muda a sala de máquinas para uma sala de máquinas diferente. Você realmente precisa ser capaz de suportar a mudança de conjuntos de servidores. Então é isso. Certamente não acontece todo dia, mas é uma parte crítica disso, ou da manutenibilidade de longo prazo desses sistemas. Um, E os autores do RAF meio que se dão tapinhas nas costas Aí está.
[17:12] um esquema que lida com isso, e bem que poderiam porque é complexo. Obrigado. Obrigado. Tudo bem, então usando essa ideia, em cerca de 1990 ou algo assim, houve dois sistemas propostos quase ao mesmo tempo. que perceberam que Você poderia usar esse sistema de voto majoritário para meio que contornar a aparente impossibilidade de evitar cérebro dividido. usando, basicamente usando três servidores em vez de dois, e fazendo votações majoritárias.
[17:44] Um, em um desses sistemas muito antigos era chamado Paxos. O artigo do Raft fala muito sobre isso. Um, E outro desses sistemas muito antigos era chamado replicação de carimbo de visão. Tchau. abreviado como VSR para replicação de carimbo de visão. E embora o Paxos seja de longe o sistema mais amplamente conhecido neste departamento, o Raft é na verdade mais próximo em design ao design da replicação de carimbo de visão. que foi inventado por pessoas do MIT.
[18:15] Um, E então há meio que uma longa história de muitas décadas desses sistemas, e eles só realmente vieram à tona e começaram a ser usados muito em sistemas distribuídos grandes implantados cerca de 15 anos atrás. uns bons 15 anos depois de terem sido originalmente inventados. Ok, então... Então deixe-me falar sobre o Raft agora. O Raft assume a forma de uma biblioteca destinada a ser incluída em algum aplicativo de serviço.
[18:50] E então se você tem um serviço replicado, cada uma das réplicas no serviço vai ser algum código de aplicação que recebe RPCs ou algo assim, mais uma biblioteca raft. E as bibliotecas raft cooperam entre si Um, para manter a replicação. Então, uma espécie de visão geral de software de uma única réplica raft é que no topo podemos pensar na réplica como tendo o código de aplicação. Então pode ser para o laboratório três, um servidor de chave-valor. Então talvez tenhamos algum servidor de chave-valor.
[19:22] E ele tem estado, a aplicação tem estado que o raft está ajudando a gerenciar, estado replicado. E para um servidor de chave-valor, vai ser uma tabela de chaves e valores. Um... *batendo* A próxima camada abaixo é uma camada raft. Então o servidor de chave-valor vai fazer chamadas de função para o RAFT, e eles vão conversar um pouco de um lado para o outro. o raft mantém um pouco de estado. Você pode ver na figura dois. E para nossos propósitos, realmente a peça mais crítica de estado é que o raft tem um log de operações.
[20:01] Obrigado. Ok. Obrigado. Amém. E em um sistema com três réplicas, na verdade vamos ter três servidores que têm exatamente a mesma estrutura idêntica e esperançosamente os mesmos dados sentados em. sentados em ambas as camadas. Obrigado. Amém. Obrigado. Obrigado. Obrigado. Obrigado. Obrigado.
[20:31] Obrigado. Certo. Fora disso, vai haver clientes. E o jogo é que Então temos cliente um, cliente dois, um monte de clientes. Os clientes realmente não sabem, os clientes são, você sabe, código externo que precisa ser capaz de usar o serviço. e A esperança é que os clientes realmente não precisem estar cientes de que estão falando com um serviço replicado. Que para os clientes vai parecer quase como se fosse apenas um servidor e eles falam com um servidor. E então os clientes na verdade enviam requisições de cliente para A chave para a camada de aplicação.
[21:05] do líder atual, a réplica que é o líder atual no Raft. E então essas vão ser requisições de nível de aplicação para um banco de dados para um servidor de chave-valor, essas podem ser requisições put e get. put pega uma chave e um valor e atualiza a tabela e get pede ao serviço para obter a chave atual, o valor atual correspondente a Alguma chave. Então isso não tem muito a ver com o Raft. É apenas interação cliente-servidor para qualquer serviço que estejamos construindo.
[21:39] Hum, mas quando um desses comandos é enviado a partir da requisição, é enviado do cliente para o servidor, o que realmente acontece é que, em um servidor não replicado, o código da aplicação executaria essa requisição e digamos, atualizaria a tabela em resposta a um put. Mas não em um serviço replicado com RAPT. Em vez disso, se assumirmos que o cliente envia uma requisição para o líder, o que realmente acontece é que a camada de aplicação simplesmente envia a requisição, a requisição do cliente, para baixo, na camada RAFT, dizendo: "Olha, aqui está uma requisição.
[22:10] Por favor, faça com que ela seja confirmada no log replicado e me avise quando terminar. E então, neste ponto, os rafts conversam entre si. Hum. até que todas as réplicas ou uma maioria das réplicas tenham essa nova operação em seus logs. Então ela está replicada, e então quando está... E o líder sabe que todas as réplicas têm uma cópia disso, só então é enviada uma notificação de volta para cima, para a camada de chave-valor, dizendo: "Ah, aquela operação que você me enviou um minuto atrás, agora foi confirmada em todas as réplicas. E então está replicada com segurança e neste ponto tudo bem executar essa operação.
[22:53] É um raft. O cliente envia uma requisição para a camada de chave-valor, a camada QDialy ainda não a executa. Então não temos certeza. porque ela ainda não foi replicada. Só quando está nos logs de todas as réplicas. Tchau. Então o Raph notifica o líder, e agora o líder realmente executa a operação, o que corresponde a... você sabe, para um put, atualizar a tabela de chave-valor; para um get, ler o valor correto da tabela, e então finalmente envia a resposta de volta ao cliente.
[23:26] Então essa é uma operação comum do Obrigado. . Ela é submetida se estiver em uma maioria. E, novamente, a razão pela qual não pode ser todas é que, se quisermos construir um sistema tolerante a falhas, ele precisa ser capaz de fazer progresso mesmo se alguns dos servidores tiverem falhado. Então-- Hum, Sim. Ela é confirmada quando está em uma maioria. Obrigado. Sim. Então, antes que o líder execute a requisição, as propriedades de valor de mercado.
[24:00] Hum... que foram replicadas. Obrigado. Uau. - Desculpe. Obrigado. líderes Sim, entendi. E então. Além disso, quando as operações finalmente são confirmadas, cada uma das réplicas envia a operação para cima. Cada camada da biblioteca wraths envia a operação para cima, para a camada de aplicação local, e a camada de aplicação local aplica essa operação ao seu estado. E então todas elas... Então, esperançosamente, todas as réplicas veem o mesmo fluxo de operações.
[24:31] elas aparecem nessas chamadas de cima na mesma ordem, são aplicadas ao estado na mesma ordem, e você sabe, assumindo que as operações são determinísticas, o que é melhor que sejam, Hum, o estado... do estado replicado evoluirá de forma idêntica em todas as réplicas. Então, tipicamente, esta tabela é do que o artigo está falando quando fala de estado. Obrigado. uma maneira diferente de ver essa interação, e uma que terá uma espécie de notação que aparecerá muito neste curso, é que Hum, uma espécie de diagrama de tempo, vou desenhar um diagrama de tempo de como as mensagens funcionam.
[25:12] Então vamos imaginar que temos um cliente, e o Servidor um é o líder, e também temos o servidor dois. Obrigado. Servidor três, e o tempo flui para baixo neste diagrama. Imaginamos o cliente enviando a requisição original para o servidor um. Obrigado. Depois disso, a camada wrapped do servidor um. Hum, envia uma append entry, é RPC. Hum, para cada uma das duas réplicas. Obrigado. Esta é apenas uma requisição comum, digamos, de put.
[25:45] Isto é, estas são requisições de PEND entries. Obrigado. O servidor agora está esperando respostas. dos servidores, das outras réplicas, assim que houver respostas de uma maioria, uma volta, incluindo o próprio líder. Então, em um sistema com apenas três réplicas, o líder só precisa esperar por uma outra réplica. para responder positivamente a uma appendentary assim que ela reúne. respostas positivas de uma maioria. Hum, o Líder executa o comando, descobre qual é a, Resposta, tipo, esquece.
[26:20] hum e envia a resposta de volta para o... E enquanto isso, é claro, você sabe, se S2 estiver realmente vivo, ele vai, você sabe, enviar de volta a resposta também, mas não estamos esperando por ele. Obrigado. É útil saber na figura dois. Obrigado. Certo, todos veem isto? Obrigado. Esta é a espécie de operação comum do sistema. Sem falhas aqui. Oh, certo. Nossa, sim. Eu gosto...
[26:53] Eu deixei de fora-- um passo importante. Neste ponto, o líder sabe, oh, eu tenho uma maioria que colocou no log deles, posso prosseguir e executar e responder sim ao cliente porque é... O Servidor dois ainda não sabe de nada. Ele só sabe, bem, você sabe, eu recebi esta requisição do, mas não sei se ela já foi confirmada. Depende de, por exemplo, se minha resposta chegou de volta ao líder. Pelo que o Servidor 2 sabe, sua resposta foi descartada pela rede, talvez o líder nunca tenha ouvido a resposta e nunca tenha decidido confirmar esta requisição. Na verdade, há outro estágio, uma vez que o, Servidor.
[27:24] percebe que uma requisição foi confirmada, ele então precisa informar às outras réplicas esse fato. E Amém. Então há... Uh... Há uma mensagem extra aqui. Exatamente qual é essa mensagem depende um pouco do que mais está acontecendo. pelo menos no RAF, não há uma mensagem de confirmação explícita. Em vez disso, a informação é transportada dentro das próximas append entries que o líder envia. As próximas RPCs de append entries que ele envia por qualquer motivo.
[27:58] Tipo, há um campo de, commit, leader commit ou algo assim nessa RPC. e Na próxima vez que o líder precisar enviar um heartbeat ou algo assim, precisar enviar uma nova requisição de cliente porque algum cliente diferente. requisitar algo, ele enviará o Hum, Novo, mais alto. valor de leader commit e nesse ponto o, uh, Hum, sim. as réplicas executarão a operação e a aplicarão ao seu estado. Sim.
[28:29] Obrigado. Obrigado. Oh, sim. Então este é um, Este é um protocolo que tem bastante conversa. Hum, e não é super rápido. De fato, você sabe, sim, o cliente envia uma requisição, a requisição tem que chegar ao servidor, o servidor fala com pelo menos, você sabe, outro... Ele envia múltiplas mensagens, tem que esperar pelas respostas, envia algo de volta. Então há um monte de tempos de ida e volta de mensagens meio que.
[29:02] embutidos aqui. teria feito sentido para a segunda parte da faculdade. Obrigado. Sim, então... Se... Então, isso depende de você como implementador exatamente quando o líder envia o índice de confirmação atualizado. Se-- as requisições de cliente voltarem só muito ocasionalmente. então o líder pode querer enviar um heartbeat ou enviar uma mensagem especial de append entries.
[29:34] Hum, Se as requisições de cliente chegarem com bastante frequência, então não importa, Se chegarem, você sabe, se chegarem mil por segundo, então, nossa, haverá outra chegando muito em breve. E então você pode transportar junto. Então, sem gerar uma mensagem extra, o que é um tanto caro. você pode levar a informação na próxima mensagem que vai enviar de qualquer forma. Hum, Na verdade, eu não acho que o momento em que as réplicas executam a requisição seja crítico porque ninguém está esperando por isso, pelo menos se não houver falhas. Se não houver falhas, a execução da requisição pelas réplicas não está realmente no caminho crítico.
[30:12] Tipo, o cliente não está esperando por elas, o cliente só está esperando o líder executar. Então pode não ser tão importante. hum Pode não afetar a latência percebida pelo cliente, tipo, exatamente como isso é encenado. Hum. Tchau. Obrigado. Obrigado. Obrigado. Obrigado. Obrigado. Obrigado. Certo. Uma pergunta que você deveria fazer é por que o sistema é tão focado em logs? O que os logs estão fazendo?
[30:51] E vale a pena tentar chegar a respostas explícitas para isso. Uma resposta para por que o sistema é totalmente focado em logs é que o log é o tipo de mecanismo pelo qual o líder ordena as operações. É vital para essas máquinas de estado replicadas que todas as réplicas apliquem não apenas as mesmas operações de cliente ao seu estado, mas as mesmas operações na mesma ordem. Mas todas elas têm que aplicar essas operações vindas dos clientes na mesma ordem. E o log, entre muitas outras coisas, é parte da maquinaria pela qual o líder atribui uma ordem às operações de cliente que chegam.
[31:32] você sabe, 10 clientes enviam operações para o líder. Ao mesmo tempo, o líder tem que escolher uma ordem, garantir que todos, todas as réplicas obedeçam a essa ordem. E o log é... O fato de o log ter slots numerados é parte de como o líder expressa a ordem que escolheu. Hum, Obrigado. Outro uso do log é que entre este ponto e este ponto, o Servidor 3 recebeu uma operação da qual ainda não tem certeza de que foi confirmada. e ele não pode executá-la ainda. Ele tem que colocar essa operação de lado em algum lugar.
[32:06] até que o incremento do valor de leader commit chegue. E então, outra coisa que o log está fazendo é que, nos seguidores, o log é o lugar onde o seguidor meio que separa operações que ainda são provisórias. que chegaram mas ainda não se sabe que foram confirmadas. E elas podem ter que ser descartadas, como veremos. Hum, Então esse é outro uso. No tipo de contrapartida desse uso no lado do líder está que o líder precisa lembrar das operações em seu log porque pode precisar retransmiti-las.
[32:38] para os seguidores. Se algum seguidor estiver offline, talvez algo tenha acontecido brevemente com sua conexão de rede ou algo assim, ele perde algumas mensagens. O líder precisa ser capaz de reenviar mensagens do blog que qualquer seguidor perca. E então o líder precisa de um lugar onde possa separar cópias de mensagens de requisições de cliente, mesmo aquelas que já executou. para poder reenviá-las ao cliente. Quero dizer, enviá-las para réplicas que perderam essa operação. E uma razão final para todos eles manterem o log é que, pelo menos no mundo da figura dois, se um servidor cair e reiniciar e quiser se juntar novamente, hum, você realmente quer que um servidor que caiu de fato reinicie e se junte novamente.
[33:20] ao cluster wrapped, caso contrário você agora está operando com apenas dois de três servidores e não pode mais sobreviver a nenhuma falha. Precisamos reincorporar servidores que falharam e reiniciaram, e o log é meio que onde, o que um servidor, um servidor reiniciado usa. O log persistido em seu disco. Porque uma das regras é que cada servidor Rath precisa gravar seu log em seu disco, onde ele ainda estará depois que cair e reiniciar. Esse log é o que o servidor usa, ele reproduz as operações nesse log desde o início para meio que criar seu estado como era quando caiu.
[33:52] e então continua a partir daí. Então o log também é usado como parte do plano de persistência. como uma sequência de comandos para reconstruir o estado. Sim. Então eu me pergunto quais cenários surgiriam em que os workers estão tentando acompanhar isso. Uh... Bem, em última análise, Ok, então a pergunta é, Suponha que o líder seja capaz de executar mil comandos de cliente por segundo e os seguidores sejam capazes de executar apenas cem comandos de cliente por segundo. Esse tipo de taxa sustentada em velocidade máxima.
[34:32] hum A, então uma coisa a notar é que as, as As réplicas, os seguidores, confirmam os comandos antes de executá-los. Então a taxa na qual eles confirmam e acumulam coisas em seus logs não é limitada. Então, você sabe, talvez eles possam confirmar, mil requisições por segundo. Se fizerem isso para sempre, então eles acumularão. logs de tamanho ilimitado porque sua taxa de execução ficará um tanto ilimitado atrás da taxa na qual o líder entregou as mensagens, meio que sob as regras do nosso jogo.
[35:06] E então o que isso significa é que eventualmente ficará sem memória. Em algum momento, depois que tiverem um bilhão, depois que ficarem um bilhão de entradas de log atrasadas, eles simplesmente, é chamado de alocador de memória. por espaço para uma nova entrada de log e isso falhará. Hum, então sim, e o RAF não, hum, o RAP não tem os controles de fluxo necessários para lidar com isso. Então eu acho que... em um sistema real, você provavelmente precisaria de algo acoplado e não precisa ser em tempo real, mas você provavelmente precisa de algum tipo de hum, comunicação adicional aqui que diga: "Oh, aqui está o quão longe eu cheguei na execução."
[35:47] Para que o líder possa dizer: bem, estou milhares de requisições à frente do ponto em que os seguidores executaram. Sim, então eu acho que provavelmente em um sistema de produção que você está tentando levar ao máximo absoluto. você bem que pode precisar de uma mensagem extra para limitar o líder se ele ficar muito à frente. Obrigado. Ok.
[36:33] - Então a questão é: se um desses servidores falhar, ele tem esse log que persistiu em disco, porque essa é uma das regras da figura dois. hum Então o servidor poderá simplesmente ser carregado de volta do disco, mas é claro, esse servidor não sabe até onde chegou na execução do log. E também não sabe, pelo menos quando reinicia pela primeira vez, pelas regras da Figura 2. Ele nem sabe quanto do log está confirmado. Então a primeira resposta para sua pergunta é que imediatamente após uma reinicialização, depois que um servidor falha e reinicia e lê esse log, ele não tem permissão para fazer nada com o log.
[37:09] porque ele não sabe até onde o sistema confirmou em seu log. Talvez esse log tenha mil entradas não confirmadas e zero entradas confirmadas para todos Então... Se o líder morrer, é claro, isso também não ajuda. Vamos supor que todos falharam. Isso está se adiantando... Está se adiantando um pouco para mim, mas vamos supor que todos falharam, e então tudo o que têm é o estado que foi marcado como não volátil na figura dois, que inclui o log e talvez o último termo.
[37:43] Hum, E então eles não sabem. Então, se houver uma falha, se todos falharem e todos reiniciarem, nenhum deles sabe. inicialmente até onde eles tinham executado antes da falha. Então o que acontece é que eles fazem eleição de líder, um deles é escolhido como líder. E esse líder, se você acompanhar o que a figura dois diz sobre como os append entries devem funcionar. o líder na verdade descobrirá como subproduto do envio do primeiro heartbeat, na verdade.
[38:14] Hum, Ele descobrirá qual é o ponto mais recente basicamente que esse Amém. todos os, que uma maioria das réplicas concorda em seu log. Porque esse é o ponto de confirmação. Outra maneira de ver isso é que, uma vez que você escolhe um líder, através do mecanismo de append entries, o líder força todas as outras réplicas a terem logs idênticos ao do líder. E nesse ponto, mais...
[38:45] Um pouco de extra, o artigo explica. Nesse ponto, como o líder sabe que forçou todas as réplicas a terem logs idênticos aos dele. Então ele sabe que, oh, todas as réplicas também devem ter um-- Deve haver uma maioria de réplicas com- que todas aquelas entradas de log nos logs que agora são idênticos também devem estar confirmadas porque estão mantidas em uma maioria de réplicas. Hum, E nesse ponto, o líder-- o código de append entries descrito na figura dois para o líder incrementará o ponto de confirmação do líder e e todos agora podem executar o log inteiro desde o início.
[39:22] e recriar seu estado do zero. possivelmente de forma extremamente trabalhosa. Hum... Então é isso que a figura dois diz. É obviamente que essa reexecução do zero não é muito atraente, mas é o que o protocolo básico faz. E veremos amanhã. versão disso é mais eficiente, usa checkpoints e falaremos sobre isso amanhã. Obrigado. Ok, então esta foi uma sequência em operação normal, sem falhas.
[39:53] Hum, hum... Outra coisa que quero mencionar brevemente é como essa interface se parece. Vocês provavelmente já viram um pouco dela. devido ao trabalho nos laboratórios, mas grosso modo, se você tem, digamos, esta camada de chave-valor, com seu estado. e a camada raft abaixo dela, há Em cada réplica há realmente duas peças principais. da interface entre elas. Há este... Hum, método pelo qual a camada de chave-valor pode retransmitir. Se um cliente envia uma requisição, a camada de chave-valor tem que entregá-la ao Raft e dizer: "Por favor, você sabe, encaixe esta requisição no log em algum lugar, e essa é a função start.
[40:34] Hum. que você verá em raft.go. E realmente ela só recebe um argumento, o comando do cliente. Obrigado. A camada de chave-valor está dizendo: "Por favor, recebi este comando. Coloque-o no log e me avise quando estiver confirmado." E a outra peça da interface é que, oportunamente, A camada raft notificará a camada de chave-valor que, ah, aquela operação que você me enviou em um comando start há um tempo atrás, que pode muito bem não ser o start mais recente. Cem comandos de cliente podem chegar e causar chamadas a start antes que qualquer um deles seja confirmado.
[41:09] oportunamente Hum, esta-- comunicação ascendente assume a forma de uma mensagem em um canal Go no qual a biblioteca Raft envia e a camada de chave-valor. deve ler. Hum. Então há este apply, Obrigado. Obrigado. É chamado de canal apply, e nele você envia uma mensagem apply. Obrigado. Não sei. Obrigado. Obrigado. Obrigado. este start e é claro que você precisa que a camada de chave-valor consiga correlacionar as mensagens que recebe no canal Apply com as chamadas a start que fez.
[41:47] Hum, E então o comando start na verdade retorna informação suficiente para que essa correlação aconteça. Ele retorna o índice a função start basicamente retorna o índice no log onde, se este comando for confirmado, o que pode não acontecer, ele será confirmado neste índice. Hum, E eu acho que também retorna o termo atual, e algumas outras coisas com as quais não nos importamos muito. E então esta mensagem apply vai conter o índice. tanto o Comando.
[42:20] Hum. Obrigado. Obrigado. Obrigado. Obrigado. Obrigado. e o índice. E todas as réplicas receberão essas mensagens apply, então todas saberão: "Oh, eu devo aplicar este comando." hum descobrir o que este comando significa e aplicá-lo ao meu estado local. E elas também recebem o índice. O índice só é realmente útil no líder para que ele possa descobrir. de quais requisições de cliente estamos falando. Obrigado. Estou curioso sobre o seguinte. O cliente está enviando sua requisição para o líder do raft em qualquer lugar.
[42:59] no qual-- clientes fazendo um get-go. Certo. sobre isso. OK. OK. Hum, acho que respondi a uma pergunta um pouco diferente. Vamos supor que o cliente envie qualquer requisição, Digamos que seja um put ou um get. Pode ser um put ou um get. Não importa muito. Vou considerar get. Hum, o ponto em que o Então o cliente envia novamente e espera por uma resposta. O ponto em que o líder enviará uma resposta é depois que o líder sabe que aquele comando está confirmado.
[43:40] Então isso vai ser uma espécie de resposta get. Tchau. *batendo* Tchau. Então o cliente não vê nada de volta. Quero dizer, e então, hum, Isso significa em termos da pilha de software real, Isso significa que a chave-valor, o RPC chegará, a camada de chave-valor chamará a função start. A função start retornará para a camada de chave-valor Mas-- A camada de chave-valor ainda não responderá ao cliente porque não sabe se é Na verdade, ela não executou a requisição do cliente agora. Ela nem sabe se algum dia executará.
[44:14] porque não tem certeza se a requisição será confirmada. E a situação em que pode não ser confirmada é se a camada de chave-valor, você sabe, recebe uma requisição, chama start, e imediatamente após start retornar, ela falha. Certamente não enviou suas mensagens apply, ou o que quer que seja. Nada foi confirmado ainda. Hum, Então o jogo é start retorna. o tempo passa, a mensagem apply relevante correspondente àquela requisição do cliente aparece para o servidor de chave-valor no canal apply e só então e isso faz com que o servidor de chave-valor execute a requisição E-- Envie uma resposta.
[44:52] Obrigado. Obrigado. Obrigado. Obrigado. Obrigado. E isso é tipo-- tudo isso é É muito importante quando Isso não importa muito se tudo correr bem. Mas se houver uma falha, agora estamos-- No ponto em que começamos a nos preocupar com falhas, estaremos extremamente interessados em, se houve uma falha, o que o cliente viu? Hum, Obrigado. Certo. E então uma coisa que surgiu é... isso é, hum, todos vocês devem estar familiarizados com isso é que, pelo menos inicialmente, uma coisa interessante sobre os logs é que eles podem não ser idênticos.
[45:30] Há toda uma série de situações em que, pelo menos por breves períodos de tempo, os finais dos diferentes... logs das réplicas podem divergir, como por exemplo, se um líder começa a enviar uma rodada de mensagens append, mas falha antes de conseguir enviar todas. Isso significará que algumas das réplicas que receberam a mensagem append acrescentarão, você sabe, aquela nova entrada de log, e as que não receberam aquela mensagem append como RPC, não as terão acrescentado. Então é fácil ver que os logs vão divergir às vezes. A boa notícia é que, a A forma como o Raft funciona na verdade acaba forçando os logs a serem idênticos depois de um tempo.
[46:07] porque pode haver diferenças transitórias, mas a longo prazo, todos os logs serão meio que modificados pelo líder até que o líder garanta que todos sejam idênticos e só então Hum. Ok. Eu acho que o próximo, há realmente dois grandes tópicos. para falar aqui sobre o Raft. Um é como funciona a eleição de líder, que é o Lab 2. E o outro é como o líder lida com os logs das diferentes réplicas, particularmente após falha.
[46:38] Então primeiro quero falar sobre eleição de líder. Amém. Obrigado. A pergunta a fazer é como o sistema sequer tem um líder? Por que precisamos de um líder? parte da resposta é que você não precisa de um líder para construir um sistema como este. É possível construir. um sistema de acordo pelo qual um cluster de servidores concorda sobre, você sabe, a sequência de entradas em um log sem ter nenhum tipo de líder designado. E de fato, o sistema Paxos original, ao qual o artigo se refere, o Paxos original não tinha um líder.
[47:11] Hum, Então é possível. A razão pela qual o Raft tem um líder é basicamente que Hum, Provavelmente há muitas razões, mas uma das principais razões é que você pode construir um sistema mais eficiente no caso comum em que todos os servidores não falham. É possível construir um sistema mais eficiente se você tiver um líder. Porque com um líder designado, todos sabem quem é o líder, Você pode basicamente obter acordo sobre requisições com uma rodada de mensagens por requisição. Enquanto sistemas sem líder têm mais o estilo de, bem, você precisa de uma primeira rodada para meio que concordar com um líder temporário, e então uma segunda rodada para realmente enviar a requisição.
[47:49] Então, é provavelmente o caso que o uso de um líder acelera o sistema por um fator de dois. Obrigado. E também torna mais fácil pensar sobre o que está acontecendo. Obrigado. Hum, O Raft passa por uma sequência de líderes, E usa esses números de termo para meio que desambiguar de qual líder estamos falando. Acontece que os seguidores não precisam realmente saber a identidade do líder. Eles realmente só precisam saber qual é o número do termo atual.
[48:20] Cada mandato tem no máximo um líder. É isso. Propriedade crítica. Você sabe, para cada mandato, pode não haver líder durante aquele mandato, ou pode haver um líder, mas não pode haver dois líderes durante o mesmo mandato. Cada mandato tem no máximo um líder. Hum, obrigado. Obrigado. Como os líderes são criados em primeiro lugar? Cada... servidor empacotado. mantém este temporizador de eleição, que é apenas um É basicamente apenas um tempo que ele registrou que diz, bem, se esse tempo ocorrer, eu vou fazer algo.
[48:55] hum E algo que ele faz é que se um período inteiro de eleição de líder expirar, sem que o servidor tenha ouvido nenhuma mensagem do líder atual, então o servidor meio que assume que provavelmente o líder atual está morto e começa uma eleição. Então temos este temporizador de eleição. E se expirar, começa uma eleição. Obrigado. .
[49:26] Obrigado. Hum, E o que significa começar uma eleição é basicamente que você incrementa o mandato o candidato, o servidor que decidiu que vai ser candidato e meio que força uma nova eleição, primeiro incrementa este mandato porque, você sabe, quer que ela seja um novo líder, ou seja, ele mesmo, E um mandato não pode ter mais de um líder, então temos que começar um novo mandato. para ter um novo líder. E então ele envia esses pedidos de voto, RPCs.
[49:57] Obrigado. Vou enviar uma rodada completa de pedidos de voto. E você pode ter que enviar apenas n menos um pedidos de voto, porque uma das regras é que um novo candidato sempre vota em si mesmo. na eleição. Hum, Então. Uma coisa a notar sobre isso é que Não é bem o caso que se um líder não falhou, não teremos uma eleição. ou se o líder falhar, então teremos uma eleição assumindo que qualquer outro servidor esteja ativo, porque algum dia os temporizadores de eleição dos outros servidores dispararão.
[50:28] Mas se o líder não falhou, ainda podemos, infelizmente, ter uma eleição. Então, se a rede estiver lenta ou perder alguns heartbeats ou algo assim, podemos acabar tendo temporizadores de eleição disparando, e mesmo que houvesse um líder perfeitamente bom, podemos, no entanto, ter uma nova eleição. Então temos que meio que manter isso em mente quando pensamos sobre correção. Hum, E o que isso por sua vez significa é que se houver uma nova eleição, pode facilmente ser o caso de o antigo líder ainda estar por aí e ainda pensar que é o líder. Como, se houver uma partição de rede, por exemplo, E o antigo líder ainda estiver vivo e bem em uma partição minoritária.
[51:02] A partição majoritária pode realizar uma eleição, e de fato uma eleição bem-sucedida, e escolher um novo líder. totalmente desconhecido para o líder anterior. Então também temos que nos preocupar com, você sabe, oh, o que aquele líder anterior vai fazer já que ele não sabe que houve uma nova eleição? Obrigado. Muito obrigado. Obrigado. Obrigado.
[51:43] Então a questão é: Existem, podem existir casos patológicos nos quais, por exemplo, A comunicação de rede unidirecional pode impedir o sistema de fazer progresso. Acredito que a resposta é sim. Certamente. Então, por exemplo, se o líder atual, Se sua rede de alguma forma falhar pela metade de um modo que o líder atual possa enviar heartbeats mas não possa receber nenhuma requisição de cliente. então os heartbeats que ele envia, que são entregues porque sua conexão de rede de saída funciona. Seus heartbeats de saída suprimirão qualquer outro servidor de iniciar uma eleição.
[52:20] Mas o fato de que seu fio de rede de entrada aparentemente está quebrado o impedirá de ouvir e executar quaisquer comandos de cliente. Era absolutamente o caso que o RAPT não é à prova de todos os hum tipos de todos os problemas malucos de rede que podem surgir. Acredito que os que pensei, acredito que são corrigíveis no sentido de que o Poderíamos resolver este aqui tendo um tipo de exigir um heartbeat bidirecional no qual se o líder envia heartbeats mas no qual Os seguidores são obrigados a responder de alguma forma aos heartbeats, como eles já são obrigados a responder.
[52:58] Mas se o líder parar de ver respostas aos seus heartbeats, Então após algum tempo em que a estação foi substituída, o líder decide renunciar. Sinto que esse problema específico. pode ser corrigido. e muitos outros também podem, mas eu, mas, Sim. você sabe Você está absolutamente certo. Coisas muito estranhas podem acontecer com redes, incluindo algumas para as quais o protocolo não está preparado. Obrigado. Obrigado. Obrigado.
[53:29] Ok, então temos essas eleições de mandato. Precisamos garantir que haja no máximo, no máximo, um líder por mandato. Como o RAF faz isso? Bem, o RAF exige, para ser eleito para um mandato, o RAF exige que um candidato obtenha votos sim de uma maioria dos servidores. Os servidores e cada servidor só dará um voto sim por mandato. Então, em qualquer mandato dado, você sabe, isso basicamente significa que em qualquer mandato dado, cada servidor vota apenas uma vez para apenas um candidato, Hum, Você não pode ter dois candidatos ambos obtendo maioria dos votos porque Todos votam apenas uma vez.
[54:06] Hum, Então a maioria-- A regra da maioria faz com que haja no máximo um candidato vencedor. Hum, e Então temos no máximo um. candidato eleito por turno. Hum... E além disso, criticamente, a regra da maioria significa que você pode ser eleito mesmo se alguns servidores tiverem falhado. Se uma minoria dos servidores falhou ou está indisponível, tem problemas de rede, ainda podemos eleger um líder. Se mais da metade falhou ou não está disponível ou está em outra partição ou algo assim, então Na verdade, o sistema simplesmente ficará lá tentando repetidamente eleger um líder.
[54:46] e nunca eleger um. se não puder de fato, se eles não forem uma maioria de servidores vivos. hum Obrigado. Se uma eleição for bem-sucedida, Todos, seria ótimo se todos soubessem disso. 7 minutos mais ou menos. Precisamos nos perguntar como todas as partes ficam sabendo o que aconteceu? O servidor que vence uma eleição, assumindo que não falhe, O servidor que vence a eleição na verdade verá uma maioria ou votos positivos para seu pedido de voto de uma maioria dos outros servidores. O candidato que está conduzindo a eleição que a vence, o candidato que vence a eleição saberá diretamente, eu obtive uma maioria de votos.
[55:23] Mas ninguém mais sabe diretamente quem foi o vencedor ou se alguém venceu. Hum, Então a maneira como o candidato informa os outros servidores é aquele heartbeat. as regras na Figura 2 dizem, oh, se você vencer uma eleição, você é imediatamente obrigado a enviar append entries. para todos os outros servidores. Agora, append entries aquele heartbeat append entries não diz explicitamente, eu venci a eleição, você sabe, eu sou um líder para o mandato 23. Hum, É um pouco mais sutil que isso. a maneira como a informação é comunicada é que Hum, Ninguém tem permissão para enviar append entries a menos que seja um líder para aquele mandato.
[56:02] Então o fato de que eu sou um, você sabe, eu sou um, Servidor e eu vi, oh, há uma eleição para o mandato 19. E então, aos poucos, eu envio append entries cujo mandato é 19, Isso me diz que alguém, não sei quem, mas alguém venceu a eleição. Hum, então é assim que os outros servidores sabem, é que eles estavam recebendo append entries para aquele mandato. E esse append entries também tem o efeito de, resetar o temporizador de eleição de todos. temporizador. Então, enquanto o líder estiver ativo e enviar mensagens de heartbeat ou append entries pelo menos, você sabe, na taxa que deveria, Toda vez que um servidor recebe um append entry, ele resetará seu temporizador de eleição e meio que suprimirá qualquer um de ser um novo candidato.
[56:46] Então, enquanto tudo estiver funcionando, os heartbeats repetidos impedirão quaisquer eleições adicionais. Claro, se a rede falhar ou pacotes forem perdidos, pode haver, no entanto, uma Mas se tudo correr bem, é meio improvável que tenhamos uma eleição. Hum, Este esquema poderia falhar no sentido, bem, não pode falhar no sentido de eleger. dois líderes para um mandato, mas pode falhar no sentido de eleger zero líderes para um mandato. Hum, A maneira mais comum de falhar é que se muitos servidores estiverem mortos ou indisponíveis ou tiverem conexões de rede ruins. Então, se você não conseguir reunir uma maioria, você não pode ser eleito, nada acontece.
[57:22] Hum, A maneira mais interessante pela qual uma eleição pode falhar é se Todos estiverem ativos. Você sabe, não há falhas, nenhum pacote é perdido. Mas-- dois líderes se tornam candidatos próximos o suficiente no tempo para que dividam o voto entre eles. ou digamos três líderes. Hum, Então suponhamos que temos três líderes. Suponhamos que temos um sistema de três réplicas Hum, Todos os seus temporizadores de eleição disparam ao mesmo tempo.
[57:53] Cada servidor vota em si mesmo. E então quando cada um deles recebe um pedido de voto de outro servidor, bem, ele já deu seu voto a si mesmo e então diz não. Então isso significa que todos os três servidores recebem um voto cada, ninguém obtém maioria, e ninguém é eleito. Hum, Então-- Seus temporizadores de eleição dispararão novamente porque O temporizador de eleição só é resetado se receber um append entries, mas não há líder, Todos terão seus temporizadores de eleição disparando novamente. E se tivermos azar, todos dispararão ao mesmo tempo. Todos votarão em si mesmos. Ninguém obterá maioria. uh Então.
[58:24] Então claramente, tenho certeza que todos vocês já perceberam a esta altura, há mais nesta história. E a maneira como o raft D-- torna a possibilidade de votos divididos improvável, mas não impossível, é randomizando esses temporizadores de eleição. Então a maneira de pensar nisso E a randomização, bem, A maneira de pensar nisso é que, então temos alguma linha do tempo, vou, hum, desenhar eventos nela. Há algum ponto em que todos receberam o último append entries.
[58:56] E então talvez o servidor tenha morrido. Vamos apenas assumir que o servidor enviou um último heartbeat e então morreu. Bem, todos os seguidores têm-- ou resetaram seus temporizadores de eleição quando receberam, ao mesmo tempo, porque provavelmente todos receberam o append entries ao mesmo tempo. Todos resetaram seus temporizadores de eleição. para algum ponto no futuro, para disparar em algum ponto no futuro. eles escolheram tempos aleatórios diferentes no futuro que então iriam disparar. Então suponho que o líder morto é o servidor um, Então agora o servidor dois e o servidor três neste ponto, definem seus temporizadores de eleição para um ponto aleatório no futuro. Digamos que o servidor dois definiu seu, hum, eu gostaria que algum temporizador disparasse aqui.
[59:38] e o servidor três definiu. Seu temporizador de eleição para disparar ali. e O ponto crucial desta imagem é que assumindo que eles escolham números aleatórios diferentes, Um deles é o primeiro e o outro é o segundo. Certo? É isso que está acontecendo aqui. E o que é o primeiro, assumindo que Esta lacuna é grande o suficiente. o que é o Primeiro, este temporizador de eleição disparará primeiro antes do temporizador de eleição do outro. desde que não tenhamos azar, ele terá tempo de enviar uma rodada completa de pedidos de voto.
[1:00:10] e obter respostas de todos onde todos estão vivos antes do segundo temporizador de eleição. disparar de qualquer outro servidor. Hum, Então. Todos veem? como a randomização dessincroniza esses candidatos. Infelizmente, há um pouco de arte em definir as constantes para esses temporizadores de eleição. Há algum tipo de requisitos concorrentes que você pode querer cumprir. Hum, Então um requisito óbvio é que o temporizador de eleição deve ser pelo menos tão longo quanto o intervalo esperado entre heartbeats.
[1:00:48] É bem óbvio que o líder envia heartbeats a cada 100 milissegundos; é melhor você garantir, sabe, não faz sentido ter o timer de eleição de ninguém disparando por 100 milissegundos, porque aí ele dispararia antes mesmo de podermos esperar uma nova entrada de append. Então o limite inferior é certamente o limite inferior é um intervalo de heartbeat. Na verdade, como a rede pode perder pacotes, você provavelmente quer que o valor mínimo do timer de eleição seja algumas vezes o intervalo de heartbeat. Então, para heartbeats de 100 milissegundos, você provavelmente quer que o menor timer de eleição possível seja, digamos, 300 milissegundos.
[1:01:25] três vezes o intervalo de heartbeat. Hum, então esse é o tipo de mínimo é o... Hum, veja, se os heartbeats são dessa frequência, você quer que o mínimo seja algumas vezes isso ou aqui. Hum, então e quanto ao máximo? Você sabe, você presumivelmente vai randomizar uniformemente sobre algum intervalo de tempos. Sabe, onde devemos definir o-- tipo de máximo. Obrigado. sobre o qual estamos randomizando. E há algumas...
[1:01:55] considerações aqui em um sistema real. hum, sabe, esse tempo máximo, uh... afeta quão rápido o sistema pode se recuperar de uma falha porque lembre-se, desde o momento em que o servidor falha até o primeiro timer de eleição disparar, o sistema inteiro fica congelado. Não há líder. Sabe, as requisições dos clientes estão sendo descartadas porque não há líder. e não estamos atribuindo um novo líder mesmo que, sabe, presumivelmente esses outros servidores estejam ativos.
[1:02:26] Então, quanto maior escolhermos esse máximo, maior o atraso que impomos aos clientes antes que a recuperação ocorra. Sabe, se isso é importante depende do tipo de desempenho que precisamos e com que frequência achamos que haverá falhas. Se a falha acontece uma vez por ano, então quem se importa? Hum, se esperamos falhas com frequência, podemos nos importar muito com quanto tempo leva para recuperar. Ok, então essa é uma consideração. A outra consideração é que essa lacuna, ou seja, a lacuna esperada no tempo entre o primeiro timer disparar e o segundo timer disparar.
[1:03:03] Hum, essa lacuna realmente, para ser útil, tem que ser maior que o tempo que o candidato leva para reunir votos de todos. Ou seja... maior que o tempo de ida e volta esperado, a quantidade de tempo que leva para enviar um RPC e obter a resposta. Sim, talvez leve 10 milissegundos para enviar um RPC e obter uma resposta, obter uma resposta de, hum, todos os outros servidores. E se for esse o caso, precisamos fazer o máximo longo o suficiente para que seja bem provável que haja 10 milissegundos de diferença entre o menor número aleatório e o próximo menor número aleatório.
[1:03:35] Hum, obrigado. E para você, hum, o código de teste vai ficar irritado se você, uh, hum, obrigado, se você não se recuperar de uma falha de líder em alguns segundos. E então, de forma pragmática, você precisa ajustar esse máximo para baixo de modo que seja altamente provável que você consiga concluir uma eleição de líder em poucos segundos. Essa não é uma restrição muito apertada.
[1:04:09] Alguma pergunta sobre os timeouts de eleição? Um ponto pequeno é que, hum, você quer... Escolher novos timeouts aleatórios toda vez que houver, toda vez que você, toda vez que eu sei-- reinicia seu timer de eleição. Ou seja, não escolha um número aleatório quando... o servidor é criado pela primeira vez e depois reutilize esse mesmo número repetidamente. Porque você faz uma escolha azarada, ou seja, você escolhe o mesmo.
[1:04:39] um servidor por azar escolhe o mesmo número aleatório que outro servidor. Isso significa que você vai ter votos divididos repetidamente. para sempre. Então é por isso que você quer quase certamente escolher um diferente, um novo, um fresco aleatório para o valor de timeout de eleição toda vez que você reinicia o timer. Obrigado. Certo, então, uma questão final sobre eleição de líder. Suponha que estamos nessa situação em que o líder antigo está particionado.
[1:05:10] Sabe, o cabo de rede está rompido, e o líder antigo está meio que lá fora com alguns clientes. e uma minoria de servidores. Há uma maioria na outra metade da rede, e a maioria na nova metade da rede elege um novo líder. E o líder antigo? Por que o líder antigo não... Obrigado. causa execução incorreta. Obrigado. Talvez seja Sim, bem ali.
[1:05:56] É assim que vai... - Fico feliz em. Tchau. e está tudo feito. Deus. Obrigado. Sim. dois problemas potenciais. Ou um tipo de não-problema é que se há um líder em outra partição e ele não tem maioria, então na próxima vez que um cliente lhe enviar uma requisição, hum, esse líder que, sabe, uma abdicação com uma minoria, sim, ele enviará append entries, mas como está na partição minoritária, não conseguirá obter respostas de volta de uma maioria dos servidores, incluindo ele mesmo. E então ele nunca...
[1:06:34] commitar a operação, ele nunca a executará. Ele nunca responderá ao cliente dizendo que a executou também. E então isso significa que, sim, um servidor antigo em uma partição diferente as pessoas podem, os clientes podem enviar uma requisição, mas eles nunca receberão respostas. hum, então nenhum cliente será enganado a pensar que aquele servidor antigo executou qualquer coisa para ele. A outra questão mais complicada, que na verdade vou falar em alguns minutos, é a possibilidade de que antes de um servidor falhar, ele envie append entries para um subconjunto.
[1:07:14] dos servidores. e então trave antes de tomar uma decisão de commit. E essa é uma questão muito interessante, que hum provavelmente passaremos uns bons 45 minutos falando sobre isso. E então, na verdade, antes de eu voltar ao tópico em geral. mais perguntas sobre eleição de líder. Obrigado. OK. hum Ok, então e quanto ao conteúdo dos logs e como, em particular, um líder recém-eleito possivelmente juntando os cacos após um crash estranho do líder anterior, como um líder recém-eleito resolve os logs possivelmente divergentes nas diferentes réplicas?
[1:08:01] a fim de restaurar um tipo de estado consistente no sistema. Hum, certo, então a primeira pergunta é: o que pode, todo esse tópico só é realmente interessante depois que um servidor trava, certo? Se o servidor permanece ativo, então relativamente poucas coisas podem dar errado. Se temos um servidor que está ativo e tem uma maioria, sabe, durante o período em que está ativo e tem maioria, hum, ele apenas diz aos seguidores como o log deve ser.
[1:08:36] E os seguidores não têm permissão para discordar. Eles são obrigados a aceitar. Eles apenas fazem pelas regras da figura dois se estiverem mais ou menos acompanhando. Sabe, eles apenas pegam o que o líder lhes envia, e append entries, e anexam ao log, e obedecem às mensagens de commit, e executam. Quase nada dá errado. As coisas que dão errado no Raft dão errado quando o líder antigo trava meio que no meio, sabe, enviando mensagens ou um novo líder trava, sabe, logo depois de ser eleito, hum... antes de ter feito algo muito útil.
[1:09:08] Então, uma coisa que nos interessa muito é como os logs podem ficar após alguma sequência de crashes? Hum... Ok. Aqui está um exemplo. Então temos três servidores. Obrigado. Obrigado. Hum, e a maneira como vou desenhar esses diagramas, porque vamos olhar muitas, tipo, situações em que os logs ficam assim, e vamos nos perguntar: isso é possível, e o que acontece se ficarem assim? Então, minha notação vai ser, vou escrever entradas de log para, hum, cada um dos servidores meio que alinhadas para indicar slots.
[1:09:46] slots correspondentes no log. E os valores que vou escrever aqui são os números de termo em vez de operações de cliente. Vou, sabe, este é o slot um, este é o slot dois. Hum, todos viram um comando do termo três no slot um, Servidor 2 e Servidor 3 viram comando também do termo três, no segundo slot, o servidor um não tem nada lá. Hum, e então a pergunta para isso, tipo a primeiríssima pergunta é: isso pode surgir?
[1:10:18] Isso poderia... configuração surgir e como? Oh. Como? Obrigado. Sim, então. Obrigado. Então.
[1:11:03] Então talvez o servidor três fosse o líder por, apenas repetindo o que você disse, talvez o servidor três seja o líder do termo três. Ele recebeu um comando que enviou para todos. Todos receberam o dependente como o log. E então eu tenho um servidor três, recebeu uma segunda requisição de um cliente. e talvez tenha enviado para todos os três servidores, mas a mensagem se perdeu no caminho para o servidor um, ou talvez o servidor um estivesse inativo na época ou algo assim, e então apenas o servidor dois Bem, o líder sempre anexa novos comandos ao seu log antes de enviar append entries. Hum, e talvez o RPC de append entry só tenha chegado ao servidor dois. Então essa situação, sabe, é tipo a situação mais simples em que na verdade os logs agora estão diferentes.
[1:11:38] E sabemos como isso poderia possivelmente... surgir. E então se o servidor três, que é o líder, travar agora, sabe, o próximo servidor eles vão precisar garantir que o servidor um Bem, primeiro de tudo, se o servidor 3 travar, ou tivermos uma eleição e algum outro líder for escolhido, sabe, duas coisas têm que acontecer. O novo líder... Ele tem que reconhecer que Isso. Hum, um comando pode ter sido commitado. Ele não tem permissão para descartá-lo. e ele precisa garantir que o servidor um preencha este espaço em branco aqui com de fato este mesmo comando que todos os outros tinham naquele slot.
[1:12:15] Hum, obrigado. Certo, então após um crash, alguém, sabe, um servidor suponha, outra maneira de isso surgir é que o servidor três pode ter enviado os append entries para o servidor dois, mas então travou antes de enviar os append entries para o servidor três. Então, se estamos elegendo um novo líder, pode ser porque tivemos um crash. antes da mensagem ser enviada. Certo, aqui está outro cenário para pensar. Hum, três servidores de novo. Obrigado. Obrigado. Obrigado. Hum, agora vou numerar os slots no log.
[1:12:47] Para que possamos nos referir a eles. Hum, temos o slot 10, 11, 12. Obrigado. 13. De novo. Isso é... Obrigado. mesma configuração exceto que agora temos no slot 12, temos o Servidor 2 como um comando do termo quatro e o servidor três tem um comando de termo do termo cinco. Obrigado. Obrigado. Então-- Antes de analisarmos isso para descobrir o que aconteceria, o que um servidor faria se visse isso, precisamos perguntar: isso poderia sequer ocorrer?
[1:13:25] Às vezes a resposta à pergunta, ah nossa, o que aconteceria se essa configuração surgisse? Às vezes a resposta é: isso não pode surgir, então não precisamos nos preocupar com isso. hum Então a pergunta é: isso poderia surgir e como? Sim. diga não, porque temos muitos. Ok. Obrigado. Obrigado. Hum, certo.
[1:14:00] E qualquer-- Certo. Obrigado. A primeira situação acontece. Amém. assistindo. amigos. - Agora, Troy. Tchau. Roger. Obrigado. O quê? Uh... Certo, sensei.
[1:14:32] pessoal. Obrigado. - Oh meu Deus. Certo. voltar. Sim. Até onde? Então deixe-me apenas repetir isso. Breve. sabemos que essa configuração pode surgir, e então a maneira como podemos obter um quatro e um cinco aqui é, suponhamos que na próxima eleição de líder, o servidor 2 seja eleito líder.
[1:15:09] Agora para o termo quatro. Eleja o líder. Você recebe uma requisição de um cliente, ele a anexa ao seu próprio log e trava. Então agora temos isso. Certo, precisamos de uma nova eleição porque o líder acabou de travar. Agora, nesta eleição, obrigado. E então agora temos que perguntar quem poderia ser eleito, ou temos que manter no fundo da mente, ah nossa, quem poderia ser eleito? Hum, então vamos afirmar que o servidor três poderia ser eleito. A razão pela qual ele poderia ser eleito é porque ele só precisa de respostas de request vote de uma maioria. Essa maioria é o servidor um e o servidor três.
[1:15:41] Você sabe, não há problema, nenhum conflito entre esses dois logs. Então o servidor três pode ser eleito para o mandato cinco, receber uma requisição de um cliente, anexá-la ao seu próprio log e travar. E é assim que você chega a esta, uh, configuração. Então você precisa ser capaz de-- Tchau. de trabalhar através dessas coisas. para chegar ao estágio de dizer, sim, isso poderia acontecer, e portanto, o Raft deve fazer algo sensato, em oposição a, isso não pode acontecer. Porque algumas coisas não podem acontecer.
[1:16:12] Um, Obrigado. Certo, então... Um, Então o que pode acontecer agora? Sabemos que isso pode ocorrer. Esperançosamente podemos nos convencer de que o Raft realmente faz algo sensato. Agora, quanto à gama de coisas, antes de falarmos sobre o que o Raph realmente faria. Precisamos ter alguma noção do que seria um resultado aceitável.
[1:16:47] Certo? e apenas olhando isto, Um, Sabemos que o comando no slot 10, uma vez que é conhecido por todas as réplicas, poderia ter sido confirmado. então não podemos descartá-lo. Similarmente, o comando no slot 11, uma vez que está na maioria das réplicas, poderia, pelo que sabemos, ter sido confirmado, então não podemos descartá-lo. O comando no slot 12, no entanto, nenhum deles poderia possivelmente ter sido confirmado. Então temos o direito. Não sabemos, não olhamos para o que o Raft realmente fará, mas o Raft tem o direito de descartar ambos, embora não tenha o direito de descartar nenhum dos comandos no 10 ou 11.
[1:17:26] Um, Este é um descarte permitido. Não é obrigatório descartar qualquer um deles. E sabemos que certamente deve descartar um, pelo menos um, porque você tem que ter conteúdos de log idênticos no final. Isto poderia ter sido confirmado. o Não podemos dizer olhando os logs exatamente até onde o líder chegou antes de travar. Então uma possibilidade é que, para este comando ou mesmo este comando, uma possibilidade é que um líder enviou as mensagens de append com um novo comando e então imediatamente travou.
[1:18:04] Então nunca recebeu nenhuma resposta de volta porque travou. Então o antigo líder não sabia se estava confirmado. E se não recebeu uma resposta de volta, isso significa que não o executou e não enviou, mas, você sabe, não enviou o índice de confirmação incrementado. E então talvez as réplicas também não o executaram. Então é realmente possível que isto não tenha sido confirmado. Então, Mesmo que o Raft não saiba, Um, Poderia ser legal para o Raft Obrigado.
[1:18:36] Se o RAP soubesse mais do que sabe, Poderia ser legal descartar esta entrada de log, porque pode não ter sido confirmada. mas porque com base nas evidências, Não há maneira de refutar que foi confirmada com base nestas evidências. Poderia ter sido confirmada. e o Raft não pode provar que não foi. Então deve tratá-la como confirmada. Certo, porque o líder pode tê-la recebido, pode ter travado logo após receber as respostas de append entry. e responder ao cliente. Então, apenas olhando para isto, não podemos descartar a possibilidade de qualquer uma das possibilidades.
[1:19:11] que o líder respondeu ao cliente, caso em que não podemos descartar esta entrada porque um cliente sabe sobre ela. Ou a possibilidade de que o líder nunca o fez, e sim, poderíamos. você sabe Então temos que assumir que foi confirmada. Pergunta? . um, Uh...
[1:19:46] Não, não há--Quero dizer, nesta situação, talvez o servidor tenha travado antes de receber o Certo, vamos continuar isto. na quinta-feira.
Ver a transcrição original em inglês
[0:01] All right, let's get started. Mm-hmm. Today, and indeed today and tomorrow, I'm going to talk about Raft. Um, both because I hope it will be helpful for you in implementing the labs. And also because You know, it's just a case study in the details of how to get state machine replication correct. So, by way of introduction to the problem, you may have noticed a pattern in the fault tolerance systems that we've looked at so far.
[0:35] Um, One is that MapReduce replicates computation but The replication is controlled, the whole computation is controlled by a single master. Um, Another example I'd like to draw your attention to is that GFS, replicates data, right, as this primary backup scheme for replicating the actual contents of files, but It relies on a single master. to choose who the primary is for every piece of data. Another example, VMware FT replicates computational right on a primary virtual machine and a backup virtual machine. But in order to figure out what to do next, if one of them seems to fail, it relies on a single test and set server.
[1:20] to help it choose, to help it ensure that exactly one of the primary or the backup takes over if there's some kind of failure. So in all three of these cases, Sure there was a replication system but sort of tucked away in a corner in the replication system there was some scheme where a single entity was required to make a critical decision about. who the primary was in the cases we care about. So, I'm going to start with the first one. a very nice thing about having a single entity decide who's gonna be the primary?
[1:52] is that it can't disagree with itself. There's only one of it, make some decision, that's the decision it made. Um, But the bad thing about having a single entity decide, like, who the primary is, is that it itself has a single point of failure. And so you can view these systems that we've looked at as sort of... pushing the real heart of the fault tolerance machinery into a little corner. That is the single entity that decides who's gonna be the primary. if there's a failure. Now, This whole thing is about how to avoid split brain. The reason why we have to have, have to be extremely careful about making the decision about who should be the primary, if there's a failure, is that otherwise we risk split brain.
[2:35] Um, And just... make this point super clear, I'm going to just remind you. what the problem is and why it's a serious problem. So, supposing for example we're um, We want to build ourselves a replicated test and set server. That is, we're worried about the fact that VMware FT relies on this test and set server to-- choose who the primary is, so let's build a replicated test and set server. And I'm going to do this, it's going to be broken, it's just an illustration for why why it's difficult to get the split brain problem correctly. So, you know, we're gonna imagine we have a network, and maybe two servers, which are supposed to be replicas of our Test and set service connected and you know, maybe two clients that need to know who's the primary right now? or actually, maybe these clients in this case are a The primary and the backup.
[3:30] um, in VMware FT. So, If it's a test and set service, then both these databases, both these servers start out with their state, that is the state of this test and flight bag being zero. the one operation their clients can send is the test and set operation which is supposed to set the of the replicated service to one, so it should set both copies. and then return the old value. So it essentially acts as a kind of simplified lock server. Um, Thank you.
[4:01] OK. The problem situation? What we worry about, split brain arises automatically. when a client can talk to one of the servers but can't talk to the other. So we're imagining either that when clients send a request, they send it to both. Um, I'm just gonna assume that now, it almost doesn't matter. So let's assume that the protocol is that the client's supposed to send ordinarily any request to both servers, And Somehow, we need to think through what the client should do if one of the servers doesn't respond.
[4:32] or what the system should do if one of the servers seems to be unresponsive. Um, Thank you. So let's imagine now the client one can contact server one but not server two. How should the system react? One possibility is that we think, well, you know, gosh, We certainly don't want to just talk to client to server one, because that would leave the second replica inconsistent if we set this value to one, but didn't also set this value to one. So maybe the rule should be that a client is always required to talk to both replicas. to both servers. for any operation and shouldn't be allowed to just talk to one of them.
[5:05] So why is that the wrong answer? Supposing the rule is, oh, in our replicated system, the client's always required to Talk to both replicas. in order to make progress. Thank you. That's not fault tolerant at all. In fact, it's worse. It's worse. than talking to a single server because now the system has a problem if either of these servers is crashed or you can't talk to it. At least with a non-replicated server, you're only depending on one server. But here we have both servers have to be alive. If we require the client to talk to both servers then. Both servers have to be live. So we can't possibly require the client to actually you know, wait for both servers to respond.
[5:48] If we don't have fault tolerance, we need it to be able to proceed. So another obvious answer is that, If the client can't talk to both, well, it just talks to the one it can talk to and figures the other one's dead. So why is that also not the right answer? The troubling scenario is if the other server is actually alive. So suppose the actual problem we're encountering is not that the server crashed, which would be good for us, but the much worse issue that something went wrong with the network cable. And that this client can talk to, client one can talk to server one but not server two.
[6:27] And there's maybe some other client out there that can talk to server two but not server one. So, If we make the rule, that if a client can't talk to both servers, that it's okay in order to be fault tolerant, that it just talked to one, then what's-- inevitably going to happen. said, this cable's going to break, thus Cutting the network in half. I'm going to-- send a test and set request to server one, Server one will set its state to one Return the previous value of 0 to client 1. And so that means client 1 will think it has the lock.
[7:00] and if it's a VMware FT, server will think it can be takeover's primary. But this replica still has zero in it. Right, so now if client two also sends a test and set request, to You know, we-- tries to send them to both, sees that server one appears to be down, follows the rule that says, well, you just send to the one server you can talk to, then it will also think that Um. it acquired, client two will also think that it acquired the lock. And so now, You know, if we were imagining this test and set server was going to be used with VMware FT, we have, you know, Both.
[7:31] uh, replica, both of these VMware, uh, machines I think they could be primary by themselves. Um, without consulting the other server. So that's a complete failure. So with this setup and two servers, It seemed like we had this, we just had to choose, either you wait for both and you're not fault-tolerant, or You wait for just one and you're not correct. And the not correct version is often called split-brain. So. Everybody see this? Thank you.
[8:03] Mm-mm. Well. Um... So this was basically where things stood. until the late 80s. And But people did want to build replicated Systems. the computers that control telephone switches, or the computers that ran banks, you know. Those places are willing to spend a huge amount of money in order to have reliable service, and so they would replicate, they would build replicated systems, and the way they would deal The way that they would-- have replication but try to rule out split brain. It's a couple of techniques. One is They would build a network that could not fail.
[8:44] And so usually what that means, and in fact you guys use networks that essentially cannot fail all the time. the wires inside your laptop you know, connecting the CPU to the DRAM are effectively a network that cannot fail. between the-- between your CPU and DRAM. So, you know, with reasonable assumptions and lots of money, and that, you know, sort of carefully controlled physical situation, like you don't want to have a cable snaking across the floor that somebody can step on, you know, it's got to be carefully physically designed setup. With a network that cannot fail, you can rule out split-brain. It's a bit of an assumption, but with enough money people get quite close to this because If the network cannot fail, that basically means that the client can't talk to server two, that means server two must be down.
[9:31] because it can't have been the network malfunctioning. So that was one way that people sort of built replication systems that didn't suffer from split-brain. Thank you. Um. Another possibility would be to have some human beings sort out the problem, that is, don't automatically do anything, instead have the clients By default, clients always have to wait for you know, both replicas respond or something, I'm never allowed to proceed with just one of them. But you can, you know, call somebody's beeper to go off, some human being goes to the machine room and sort of looks at the two replicas and, either turns one off, to make sure it's definitely dead.
[10:08] or verifies that one of them has indeed crashed, and that the other is alive. And so you're essentially using the human as a as the tiebreaker, and the human is a you know. if they were a computer, it would be a single point of failure themselves. club. So for a long time, people used one or the other of these schemes in order to build replicated systems, and it's not, you know, They can be made to work. The humans don't respond very quickly. And the network that cannot fail is expensive, but it's not not doable. Um, But it turned out that you can actually build automated failover systems Um, that can work correctly in the face of flaky networks, of networks that could fail.
[10:50] that can partition. So this split of the network in half where the two sides operate but can't talk to each other, That's usually called a partition. Um. Thank you. Thank you. And the big insight that people came up with in order to build automated replication systems that don't suffer from split-brain is the idea of a majority vote. And so this is-- Thank you. Thank you. Thank you. a concept that shows up in like every other sentence practically in the Raft paper.
[11:24] It's a sort of fundamental-- um way of proceeding. The first step is to have an odd number of servers instead of an even number of servers. Like, one flaw here is that it's a little bit too symmetric. The two sides of the split here, they just look the same. They run the same software, they're going to do the same thing, and that's not good. But if you have an odd number of servers, Then, It's not symmetric anymore. Right. At least a single network split will be presumably two servers on one side and one server on the other side and they won't be symmetric at all.
[11:57] And that's part of what majority voting schemes are. appealing to. So, basic idea is you have an odd number of servers, in order to make progress of any kind, so in Raft, elect a leader, or cause a log entry to be committed, in order to make any progress at each step, You have to assemble a majority... of the servers, more than half, more than half of all the servers, in order to sort of approve that step, like vote for a leader, accept a new log entry and commit it. Um, So, you know, the most...
[12:29] uh... Straightforward way is to have two or three servers required to do anything. Um, One reason this works, of course, is that If there's a partition, There can't be more than one partition with a majority of the servers in it. That's one way to look at this. A partition can have one server in it, which is not a majority. Or maybe you can have two, but if one partition has two, then the other partition has to have only one server in it. and therefore will never be able to assemble a majority and won't be able to make progress.
[13:03] Um, And just... To be totally clear, When we're talking about a majority, it's always a majority out of all of the servers. not just the live servers. This is a point that confused me for a long time, If you have a system with three servers, and maybe some of them have failed or something, If you need to assemble a majority, it's always two out of three. even if you know that one has failed. The majority is always out of the total number of servers. um, There's a more general formulation of this. Because of majority voting system in which two out of three are required to make progress, it can survive the failure of one server.
[13:40] Right. Any two servers are enough to make progress. If you need to be able to, if you're, you know, you're worried about how reliable your servers are or God. you can build systems that have more servers, and so the more general formulation is If you have two f plus one servers, then you can withstand F failures. Bye. So if it's three, That means f is one. In a system with three servers, you tolerate F servers, F1 failure and still keep going.
[14:16] Thank you. Thank you. Thank you. All right. Often these are called quorum systems because the two out of three is sometimes held a quorum. Thank you. Okay, so one property I've already mentioned about these majority voting systems is that Um, At most one partition can have a and therefore if the network's partitioned, We can't have both halves of the network making progress. Another more subtle thing that's going on here is that Um, If you always need a majority.
[14:49] of the servers to proceed. And you go through a sort of succession of operations in which reach operation somebody assembled a majority like. you know, votes for leaders or Let's say votes for leaders for Raft. At every step, the majority you assemble for that step must contain at least one server that was in the previous majority. any two majorities overlap in at least one server. And it's really that property, more than anything else that Raft is relying on.
[15:22] Um, to avoid split brain. It's the fact that, for example, when you have a leader, a successful leader election, and a leader assembles votes from a majority, its majority is guaranteed to overlap with the previous leader's majority. So, for example, the new leader is guaranteed to know about the term number used by the previous leader. because its majority overlaps with the previous leader's majority and everybody in the previous leaders majority knew about the previous leaders term number. Similarly, anything the previous-- leader could have committed must be present in a majority of the servers in Wrapped, and therefore any new leader's majority must overlap at at least one server.
[16:01] with every committed entry. from the previous leader. This is a big part of Why it is that... Wrapped is correct. Any questions about... the general concept of majority voting system. Yeah? Is it also common to add servers? Like add the processing ? JONATHAN GRUBER: Is it possible to add servers? I think it's possible. It's possible, you know, section something, maybe six in the how to add or change the set of servers.
[16:41] It's possible. You need to do it in a long running system. If you're running your system for five, 10 years, you're going to need to replace the servers after a while. you know, one of them fails permanently, or you upgrade, or you move machine rooms to a different machine room. You really do need to be able to support changing sets of servers. So that's it. It certainly doesn't happen every day, but it's a critical part of this, or long-term maintainability of these systems. Um, And the RAF authors sort of pat themselves on the back There you have it.
[17:12] a scheme that deals with this, which as well they might because it's complex. Thank you. Thank you. All right, so using this idea, in about 1990 or so, there were two systems proposed at about the same time. that realize that You could use this majority voting system to kind of get around the apparent impossibility of avoiding split brain. by using, basically by using three servers instead of two, and taking majority votes.
[17:44] Um, in the one of these very early systems was called Paxos The Raft paper talks about this a lot. Um, And another of these very early systems was called view stamp replication. Ciao. abbreviated as VSR for view stamp replication. And even though Paxos is by far the more widely known system in this department, Raft is actually closer to design in design to view step by few stamp replications. which was invented by people at MIT.
[18:15] Um, And so there's sort of a long, many decade history of these systems and they only really came to the forefront and started being used a lot in deployed big distributed systems about 15 years ago. a good 15 years after they were originally invented. Okay, so... So let me talk about Rath now. Raft takes the form of a library intended to be included in some service application.
[18:50] And so if you have a replicated service, each of the replicas in the service is going to be some application code which receives RPCs or something, plus a raft library. And the raft libraries cooperate with each other Um, to maintain replication. So, a sort of software overview of a single-raft replica is that at the top we can think of the replica as having the application code. So it might be for lab three, a key value server. So maybe we have some key value server.
[19:22] And it has state, the application has state that raft is helping it manage, replicated state. And for a key value server, it's going to be a table of keys and values. Um... *knocking* The next layer down is a raft layer. So the key value server is going to make function calls into RAPT, and they're going to chit chat back and forth a little bit. raft keeps a little bit of state. You can see it in figure two. And for our purposes, really the most critical piece of state is that raft has a log of operations.
[20:01] Thank you. Okay. Thank you. Amen. And in a system with three replicas, we're actually going to have three servers that have exactly the same identical structure and hopefully the very same data sitting in. sitting at both layers. Thank you. Amen. Thank you. Thank you. Thank you. Thank you. Thank you.
[20:31] Thank you. Right. Outside of this, there's going to be clients. And the game is that So we have client one, client two, a whole bunch of clients. The clients don't really know, the clients are, you know, External code that needs to be able to use the service. and The hope is the clients won't really need to be aware that they're talking to a replicated service. That to the clients it'll look almost like it's just one server and they talk to one server. And so the clients actually send client requests to The key to the application layer.
[21:05] of the current leader, the replica that's the current leader in Raft. And so these are going to be application level requests for a database for a key value server, these might be put and get requests. put takes a key and a value and updates the table and get ask the service to get the current key, current value corresponding to Some key. So this has nothing much to do with Raft. It's just client-server interaction for whatever service we're building.
[21:39] Um, But once one of these commands gets sent from the request, gets sent from the client to the server, what actually happens is on a non-replicated server, the Application code would like execute this request and say update the table in response to a put. but not in a RAPT-replicated service. Instead, if assuming the client sends a request to the leader, what really happens is the application layer. simply sends the request, the client's request, down into the RAFT layer to say, "Look, here's a request.
[22:10] Please get it committed. into the replicated log and tell me when you're done. And so at this point, the rafts chit chat with each other. Um. until all the replicas or a majority of the replicas get this new operation into their logs So it is replicated, and then when it's And the leader knows that all of the replicas of a copy of this only then is wrapped send a notification up, back up to the key value layer saying, "Aha, that operation you sent me a minute ago, It's been now committed into all the replicas And so it's safely replicated and at this point it's okay to execute that operation.
[22:53] It's a raft. The client sends a request to the key value layer, QDialyLayer does not execute it yet. So we're not sure. because it hasn't been replicated. Only when it's in the logs of all the replicas. Bye. Then Raph notifies the leader, and now the leader actually executes the operation, which corresponds to... you know, for a put, updating the key value table for a get, reading the correct value out of the table, and then finally sends the reply back to the client.
[23:26] So that's an ordinary operation of the Thank you. . It's submitted if it's in a majority. And again, the reason why I can't be all is that if we want to build a fault tolerance system, It has to be able to make progress even if Some of the servers have failed. So-- Um, Yeah. It's committed when it's in a majority. Thank you. Yes. So before the leader executes the request markets, devalue properties.
[24:00] Um... that have been replicated. Thank you. Wow. - I'm sorry. Thank you. leaders Yeah, I got that. And so. In addition, when the operations finally committed, each of the replicas sends the operation up. Each of the wraths Library layer sends the operation up to the local application layer, and the local application layer applies that operation to its state. And so they all... So hopefully all the replicas seem the same stream of operations.
[24:31] they show up in these up calls in the same order, they get applied to the state in the same order, and you know, assuming the operations are deterministic, which they better be, Um, The state... of the replicated state will evolve. in identically on all the replicas. So typically this table is what the paper is talking about when it, Talks about state. Thank you. a different way of viewing this interaction and one that'll sort of notation that will come up a lot in this course is that Um, A sort of time diagram, I'll draw you a time diagram of how the messages work.
[25:12] So let's imagine we have a client, and Server one is the the leader, and we also have server two. Thank you. Server three, and time flows downward on this diagram. We imagine the client sending the original request. to server one Thank you. After that, server one's wrapped layer. Um, sends an append entry, it's RPC. Um, to each of the two replicas. Thank you. This is just an ordinary, let's say, put request.
[25:45] This is, these are PEND entries requests. Thanks. The server's now waiting for replies. from the servers, from the other replicas, as soon as replies from a majority, a ride back, including the leader itself. So in a system with only three replicas, the leader only has to wait for one other replica. to respond positively to an appendentary as soon as it assembles. positive responses from a majority. Um, the Leader executes the command, figures out what the, Answer is like forget.
[26:20] um and sends the reply back to the... And meanwhile, of course, you know, if S2 is actually alive, it'll, you know, Sendback gets response too, but we're not waiting for it. Thank you. It's useful to know in figure two. Thank you. All right, everybody see this? Thank you. This is the sort of ordinary operation of the system. No failures here. Oh, okay. Gosh, yeah. I like...
[26:53] I left out-- important step. At this point, the leader knows, oh, I got a majority of put it in their log, I can go ahead and execute it and reply yes to the client because it's Server two doesn't know anything yet. It just knows, well, you know, I got this request from the, but I don't know if it's committed yet. Depends on, for example, whether my reply got back to the leader. For all Server 2 knows, its reply was dropped by the network, Maybe the leader never heard the reply and never decided to commit this request. There's actually another stage, once the, Server.
[27:24] realizes that a request is committed, it then needs to tell the other replicas that fact. And Amen. So there's... Uh... There's an extra message here. Exactly what that message is depends a little bit on what else is going on. at least in RAF, there's not an explicit commit message. Instead, the information is piggybacked inside the next append entries that the leader sends out. The next append entries RPC it sends out for whatever reason.
[27:58] Like there's a, commit, leader commit or something field in that RPC. and The next time the leader needs to have to send a heartbeat or something, needs to send out a new client request because some different Client. request something, it'll send out the Um, New, higher things. leader commit value and at that point the, uh, Um, yeah. replicas will execute the operation and apply it to their state. Yes.
[28:29] Thank you. Thank you. Oh, yes. So this is a, This is a protocol that has quite a bit of chit-chat in it. Um, and it's not, Super fat. Indeed, you know, yeah, the client sends in a request, the request has to get to the server, the server talks to at least, you know, another... It sends out multiple messages, has to wait for the responses, sends something back. So there's a bunch of message round-trip times kind of.
[29:02] embedded here. would have made sense to the second part of the faculty. Thank you. Yeah, so... If... So, This is up to you as the implementer actually exactly when the leader, sends out the updated commit index. If-- Client requests a um, come back only very occasionally. then the leader may want to send out a heartbeat or send out a special append entries message.
[29:34] Um, If client requests come quite frequently, then it doesn't matter, If they come, you know, if there's a thousand arrive per second, then, geez, there'll be another one along very soon. And so you can piggyback. So without generating an extra message, which is somewhat expensive. you can get the information out on the next message you are going to send anyway. Um, In fact, I don't think the, time at which the replicas execute the request - It's critical because nobody's waiting for it, at least if there's no failures. If there's no failures, the replicas executing the request isn't really on the critical path.
[30:12] Like the client isn't waiting for them, the client's only waiting for the leader to execute. So it may not be that important. um It may not affect client perceived latency, sort of exactly how this gets staged. Um. Bye. Thank you. Thank you. Thank you. Thank you. Thank you. Thank you. All right. One question you should ask is why is the system so focused on logs? What are the logs doing?
[30:51] And it's sort of worth trying to come up with explicit answers to that. One answer to why the system is totally focused on logs. is that The log is, the kind of mechanism by which the leader orders operations. It's vital for these replicated state machines that all the replicas apply not just the same client operations to their start, but the same operations in the same order. But they all have to apply these operations coming from the clients in the same order. And the log, among many other things, is part of the machinery by which the leader assigns an order to the incoming client operations.
[31:32] you know, 10 clients send operations to the leader. At the same time, the leader has to pick Pick an order, make sure everybody, all the replicas obey that order. And the log is The fact that the log has numbered slots. is part of how the leader expresses the order it's chosen. Um, Thank you. Another use of the log is that between this point and this point, Server 3 has received an operation that it is not yet sure is committed. and it cannot execute it yet. It has to put this operation aside somewhere.
[32:06] until the increment to the leader commit value comes in. And so, another thing that the log is doing is that, on the followers, the log is the place where the follower sort of sets aside operations that are still tentative. that have arrived but are not yet known to be committed. And they may have to be thrown away, as we'll see. Um, So that's another use. On the sort of dual of that use on the leader side is that the leader needs to remember operations in its log because it may need to retransmit them.
[32:38] to followers. If some follower is offline, maybe it's something briefly happened to its network connection or something, misses some messages. The leader needs to be able to resend blog messages that any followers miss. And so the leader needs a place where I can set aside copies of messages of client requests, even ones that it's already executed. in order to be able to resend them to the client. I mean, we send them to replicas that missed miss that operation. And a final reason for all of them to keep the log is that at least in the world of figure two, If a server crashes and restarts and wants to rejoin um You really want a server that crashes to in fact restart and rejoin.
[33:20] the wrapped cluster, otherwise you're now operating with only two out of three servers and you can't survive any more failures. We need to reincorporate failed and rebooted servers, and the log is sort of where, what a server, a rebooted server uses. The log persisted to its disk. Because one of the rules is that Each Rath server needs to write its log to its disk, where it will still be after it crashes and restarts. That log is what the server uses, it replays the, operations in that log from the beginning to sort of create its state as of when it crashed.
[33:52] and then it carries on from there. So the log is also used as part of the persistence plan. as a sequence of commands to rebuild the state. Yes. So I'm wondering what scenarios would arise where the workers are trying to follow up with it. Uh... Well, ultimately, Okay, so the question is, Suppose the leader is capable of executing a thousand client commands a second and the followers are only capable of executing a hundred client commands per second. That sort of sustained rate at full speed.
[34:32] um The, so one thing to note is that the, the The replicas, the followers, acknowledge commands before they execute them. So the rate at which they acknowledge and accumulate stuff in their logs is not limited. So, you know, maybe they can acknowledge it, a thousand requests per second. If they do that forever, then they will build up. unbounded size logs because their execution rate falls will fall an unbounded amount behind the rate at which the leader has given the messages, sort of under the rules of our game.
[35:06] And so what that means is it will eventually run out of memory. At some point, after they have a billion, after they fall a billion log entries behind, they'll just like, they're called a memory allocator. for space for a new log entry and it will fail. Um, So yeah, and RAF doesn't, um RAP doesn't have the flow controls that's required to cope with this. So I think... in a real system, you would actually need probably piggybacked and doesn't need to be real time, but you probably need some kind of um, additional communication here that says, "Oh, here's how far I've gotten in execution.
[35:47] So that the leader can say, well, I'm too many thousands of requests ahead of the point at which the followers have executed. Yeah, so I think there's probably in a production system that you're trying to push to the absolute max. you might well need an extra message to throttle the leader if it got too far ahead. Thank you. Okay.
[36:33] - So the question is, If one of these servers crashes, It has this log that it persisted to dis, 'cause that's one of the rules of figure two. um So the server will be able to be just logged back from disk, but of course, That server doesn't know how far it got in executing the log. And also it doesn't know, at least when it first reboots, by the rules of Figure 2. It doesn't even know how much the log is committed. So the first answer to your question is that immediately after a restart, after a server crashes and restarts and reads this log, it is not allowed to do anything with the log.
[37:09] because it does not know how far the system has committed in its log. Maybe this log has a thousand uncommitted entries and zero committed entries for all So... If the leader dies, of course, that doesn't help either. Let's suppose they've all crashed. This is getting ahead of... It's getting a bit ahead of me, but we'll suppose they've all crashed, and so all they have is the state that was marked as non-volatile in figure two, which includes the log and maybe the latest term.
[37:43] Um, And so they don't know. So if there's a crash, if they all crash and they all restart, None of them knows. initially how far they had executed before the crash. So what happens is, they do leader election, one of them gets picked as a leader. And that leader, if you sort of track through what figure two says about how append entries are supposed to work. the leader will actually figure out as a byproduct of sending out the first heartbeat really.
[38:14] Um, It'll figure out what the latest point is basically that that Amen. all of the, that a majority of the replicas agree on their law. Because that's the commit point. Another way of looking at it is that once you choose a leader, through the append entries mechanism, the leader forces all of the other replicas to have identical logs to the leader. And at that point, plus...
[38:45] A little bit of extra, the paper explains. At that point, since the leader knows that it's forced all the replicas to have a have logs that are identical to it. Then it knows that, oh, all the replicas must also have a-- There must be a majority of of replicas with- that all those log entries in the logs which are now identical must also be committed because they're held on a majority of replicas. Um, And at that point, the leader-- append entries code described in figure two for the leader will increment the leader's commit point and and everybody can now execute the entire log from the beginning.
[39:22] and recreate their state from scratch. possibly extremely laboriously. Um... So that's what figure two says. It's obviously this re-executing from scratch is not very attractive, but That's what the basic protocol does. And we'll see tomorrow. version of this is more efficient, uses checkpoints and We'll talk about it tomorrow. Thank you. Okay, so this was a sequence in sort of ordinary, non-failure operation.
[39:53] Um, um... Another thing I want to briefly mention is what this interface looks like. You've probably all seen a little bit of it. due to working on the labs, but roughly speaking, if you have, let's say, this key value layer, with its state. and the raft layer underneath it, there's On each replica there's really two main pieces. of the interface between them. There's this... Um, method by which the key value layer can relay. If a client sends in a request, the key value layer has to give it to Rath and say, "Please, you know, fit this request into the log somewhere, and that's the start function.
[40:34] Um. that you'll see in raft.go. And really it just takes one argument, the client command. Thank you. The key value layer is saying, "Please, I got this command. Stick it into the log and tell me when it's committed." And the other piece of the, interface is that by and by, The raf layer will notify the key value layer that, aha, that operation that you sent to me in a start command a while ago, which may well not be the most recent start. A hundred client commands could come in and cause calls to start before any of them are committed.
[41:09] by and by Um, this-- upward communication is takes the form of a message on a Go channel that the Raph library sends on and the key value layer. is supposed to read from. Um. So there's this apply, Thank you. Thank you. It's called the apply channel, and on it you send an apply message. Thank you. I don't know. Thank you. Thank you. Thank you. this start and of course you need the Key value layer needs to be able to match up messages it receives on the Apply channel with calls to start that it made.
[41:47] Um, And so the start command actually returns enough information for that matchup to happen. It returns the index the start functions basically returns the index in the log where if this command is committed, which it might not be, it'll be committed at this index. Um, And I think it also returns the current term, and some other stuff we don't care about very much. And then this apply message is going to, contain the index. both the Command.
[42:20] Um. Thank you. Thank you. Thank you. Thank you. Thank you. and the index. And all the replicas will get these apply messages, so they'll all know, "Oh, I should apply this command." um figure out what this command means and apply it to my local state. And they also get the index. The index is really only useful on the leader so it can, figure out. what client requests we're talking about. Thank you. I'm curious about the following. The client is sending their request to the back, rock leader any place.
[42:59] at which-- clients by making a get-go. Right. about that. OK. OK. Um, I think I answered a slightly different question. Let's suppose the client sends any request in, Let's say it's a put or a get. It could be a put or a get. It doesn't really matter. I'll take it to get. Um, the point at which the So the client sends in again and waits for a response. The point at which the leader will send a response at all is after the leader knows that command is committed.
[43:40] So this is going to be a sort of get reply. Bye. *knocking* Bye. So the client doesn't see anything back. I mean it, and so, um, That means in terms of the actual software stack, That means that the key value, the RPC will arrive, the key value layer will call the start function. The start function will return to the key value layer But-- The key value layer will not yet reply to the client because it does not know if it's Actually, it hasn't executed the client's request now. It doesn't even know if it ever will.
[44:14] because it's not sure if the request is going to be committed. And the situation in which it may not be committed is if the key value layer, you know, gets a request, calls start, and immediately after start returns, it crashes. It certainly hasn't sent out its apply, pen messages, or whatever. Nothing's been committed yet. Um, So the game is start returns. time passes, the relevant, apply message corresponding to that client request appears to the key value server on the apply channel and only then and that causes the key value server to execute the request And-- Send a reply.
[44:52] Thank you. Thank you. Thank you. Thank you. Thank you. And that's like-- all this is It's very important when it It doesn't really matter if everything goes well. But if there's a failure, we're now-- At the point where we start worrying about failures, we'll be extremely interested in, if there was a failure, what did the client see? Um, Thank you. All right. And so one thing that has come up is... that's, um, all of you should be familiar with is that, at least initially, one interesting thing about the logs is that they may not be identical.
[45:30] There are a whole bunch of situations in which, at least for brief periods of time, the ends of the different... replica's logs may diverge, like for example, if a leader starts to send out a round of append messages, but crashes before it's able to send all of them out. That'll mean that some of the replicas that got the append message will append you know, that new log entry, and the ones that didn't get that pin message as RPC, won't have appended them. So it's easy to see that the logs are going to diverge sometimes. The good news is that, the The way Raft works actually ends up forcing the logs to be identical after a while.
[46:07] 'cause there may be transient differences, but in the long run, all the logs will sort of be modified by the leader until the leader ensures they're all identical and only then Um. Okay. I think the next, there's really two big topics. to talk about here for Raft. One is how leader election works, which is Lab 2. And the other is, how the leader deals with the different replicas logs, particularly after failure.
[46:38] So first I want to talk about leader election. Amen. Thank you. Question to ask is how come the system even has a leader? Why do we need a leader? that Part of the answer is you do not need a leader to build a system like this. It is possible to build. an agreement system by which a cluster of servers agrees on, you know, the sequence of entries in a log without having any kind of designated leader. And indeed, The original Paxos system, which the paper refers to, original Paxos did not have a leader.
[47:11] Um, So it's possible. The reason why Raft has a leader is basically that Um, There's probably a lot of reasons, but one of the foremost reasons is that you can build a more efficient in the common case in which all The servers don't fail. It's possible to build a more efficient system if you have a leader. Because with a designated leader, everybody knows who the leader is, You can basically get agreement on requests with one round of messages per request. Whereas leaderless systems have more of the flavor of, well, you need a first round to kind of agree on a temporary leader, and then a second round to actually send out the request.
[47:49] So, It's probably the case that use of a leader speeds up the system by a factor of two. Thank you. And it also makes it sort of easier to think about what's going on. Thank you. Um, Raft goes through a sequence of leaders, And It uses these term numbers in order to sort of disambiguate which leader we're talking about. It turns out the followers don't really need to know the identity of the leader. They really just need to know what the current term number is.
[48:20] Each term has at most one leader. That's it. critical property You know, for every term, there might be no leader during that term, or there might be one leader, but there cannot be two leaders. during the same term. Every term has at most one leader. Um, Thank you. Thank you. How do the leaders get created in the first place? Every... wrapped server. keeps this election timer, which is just a It's basically just a time that it has recorded that says, well, if that time occurs, I'm going to do something.
[48:55] um And something that it does is that if an entire leader election period expires, without the server having heard any message from the current leader then the server sort of assumes probably that the current leader is dead and starts an election. So we have this election timer. And if it expires, start an election. Thank you. .
[49:26] Thank you. Um, And what it means to start an election is basically that you increment the term the candidate, the server that's decided it's going to be a candidate and sort of force a new election, first increments this term because, you know, wants her to be a new leader, namely itself, And a term can't have more than one leader, so we've got to start a new term. in order to have a new leader. And then it sends out these request votes, RPCs.
[49:57] Thank you. I'm going to send out a full round of request votes. And you may only have to send out n minus one request votes, because one of the rules is that a new candidate always votes for itself. in the election. Um, So. One thing to note about this is that It's not quite the case that if a leader didn't fail, we won't have an election. or if the leader does fail, then we will have an election assuming any other server is up, because someday the other server's election timers will go off.
[50:28] But if the leader didn't fail, we might still, unfortunately, get an election. So if the network is slow or drops a few heartbeats or something, we may end up having election timers go off, and even though there was a perfectly good leader, we may nevertheless have a new election. So we have to sort of keep that in mind when we're thinking about correctness. Um, And what that in turn means is that if there's a new election, it could easily be the case that the old leader is still hanging around and still thinks it's the leader. Like, if there's a network partition, for example, And the old leader is still alive and well in a minority partition.
[51:02] The majority partition may run an election, and indeed a successful election, and choose a new leader. totally unknown to the previous leader. So we also have to worry about, you know, oh, what's that previous leader going to do since it does not know there was a new election? Thank you. Very much. Thank you. Thank you.
[51:43] So the question is, Are there, can there be pathological cases in which, for example, One way network communication can prevent the system from making progress. I believe the answer is yes. Certainly. So for example, if the current leader, If its network somehow half fails in a way the current leader can send out heartbeats but can't receive any client requests. then the heartbeats that it sends out, which are delivered because it's outgoing network connection works. It's outgoing heartbeats will suppress any other server from starting an election.
[52:20] But the fact that it's incoming network wire apparently is broken will prevent it from hearing and executing any client commands. It was absolutely the case that RAPT is not proof against all um sort of all crazy network problems that can come up. I believe the ones I've thought about, I believe are fixable in the sense that the We could solve this one by having a sort of requiring a two-way heartbeat in which if the leader sends out heartbeats but in which Followers are required to reply in some way to heartbeats, like as they are already required to reply.
[52:58] But if the leader stops seeing replies to its heartbeats, Then after some amount of time in which the season was replaced, the leader decides to step down. I feel like that's specific issue. can be fixed. and many others can too, but I, but, Yeah. you know You're absolutely right. Very strange things can happen to networks, including some that the protocol is not prepared for. Thank you. Thank you. Thank you.
[53:29] Okay, so we got these meter elections. We need to ensure that there is at most, at most, one leader per term. How does RAF do that? Well, RAF requires, in order to be elected for a term, RAF requires a candidate to get yes votes from a majority of the servers. The servers and each server will only cast one yes vote per term. So in any given term, you know, it basically means that in any given term, each server votes only once for only one candidate, Um, You can't have two candidates both get a majority of votes because Everybody votes only once.
[54:06] Um, So the majority's-- The majority rule causes there to be at most one winning candidate. Um, and So then we get at most one. candidate elected per turn. Um... And in addition, critically, the majority rule means that you can get elected even if some servers have crashed. If a minority of servers are crashed or unavailable, have network problems, we can still elect a leader. If more than half have crashed or are not available or are in another partition or something, then Actually, the system will just sit there trying again and again to elect a leader.
[54:46] and never elect one. if it cannot in fact, if they're not a majority of live servers. um Thank you. If an election succeeds, Everybody, it'd be great if everybody learned about it. 7 minutes or so. We need to ask ourselves how do all the parties learn what happened? The server that wins an election, assuming it doesn't crash, The server that wins election we'll actually see a majority or positive votes for its request vote from a majority of the other servers. The candidate that's running the election that wins it, the candidate that wins the election will actually know directly, I got a majority of votes.
[55:23] But nobody else directly knows who the winner was or whether anybody won. Um, So the way that the candidate informs other servers is that heartbeat. the rules in Figure 2 say, oh, if you win an election, you're immediately required to send out independentries. to all the other servers. Now, dependentries that heartbeat dependent entries doesn't explicitly say, I won the election, you know, I'm a leader for term 23. Um, It's a little more subtle than that. the way the information is communicated is that Um, No one is allowed to send out and append entries unless they're a leader for that term.
[56:02] So the fact that I'm a, you know, I'm a, Server and I saw, oh, there's an election for term 19. And then by and by, I send in append entries whose term is 19, That tells me that somebody, I don't know who, but somebody won the election. Um, so that's how the other servers know, is they were receiving append entries for that term. And that append entries also has the effect of, resetting everybody's election time. timer. So as long as the leader is up and it sends out heartbeat messages or append entries at least, you know, at the rate it's supposed to, Every time a server receives an append entry, it'll reset its selection timer and sort of suppress anybody from being a new candidate.
[56:46] So as long as everything's functioning, the repeated heart beats will prevent any further elections. Of course, if the network fails or packets are dropped, there may nevertheless be an But if all goes well, we're sort of unlikely to get an election. Um, This scheme could fail in the sense, well, it can't fail in the sense of electing. two leaders for a term, but it can fail in the sense of electing zero leaders for a term. Um, The sort of morning way it may fail is that if too many servers are dead or unavailable or have bad network connections. So if you can't assemble a majority, you can't be elected, nothing happens.
[57:22] Um, The more interesting way in which an election can fail is if Everybody's up. You know, there's no failures, no packets are dropped. But-- two leaders become candidate close together enough in time that they split the vote between them. or say three liters. Um, So supposing we have three leaders. Supposing we have a three replica system Um, All their election timers go off at the same time.
[57:53] Every server votes for itself. And then when each of them receives a request vote from another server, well it's already cast its vote for itself and so it says no. So that means that all three of the servers each get one vote each, nobody gets a majority, and nobody's elected. Um, So then-- Their election timers will go off again because The election timer is only reset if it gets an append entries, but there's no leader, They'll all have their election timers go off again. And if we're unlucky, they'll all go off at the same time. They'll all vote for themselves. Nobody will get a majority. uh So.
[58:24] So clearly, I'm sure you're all aware at this point, there's more to this story. And the way raft D-- makes the possibility of split votes unlikely, but not impossible, is by randomizing these election timers. So the way to think of it And the randomization, well, The way to think of it is that, so we have some timeline, I'm going to, um, draw events on. There's some point at which everybody received the last append entries.
[58:56] And then maybe the server died. Let's just assume the server sent out a last heartbeat and then died. Well, all of the followers have-- or reset their election timers when they received, at the same time, because they probably all received the append entries at the same time. They all reset their election timers. for some point in the future, to go off at some point in the future. they chose different random times in the future which then were gonna go off. So I suppose the dead leader is server one, So now server two and server three at this point, set their election timers for a random point in the future. Let's say server two set their, um, I'd like some timer to go off here.
[59:38] and server three set. It's election timer to go off there. and The crucial point about this picture is that assuming they pick different random numbers, One of them is first and the other one is second. Right? That's what's going on here. And the one that's first, assuming This gap is big enough. the one that's First, this election timer will go off first before the other one's election timer. as long as we're not unlucky, it'll have time to send out a full round of Vote requests.
[1:00:10] and get answers from everybody where everybody's alive before the second election. timer goes off from any other server. Um, So. Does everybody see? how the randomization desynchronizes these candidates. Unfortunately, there's a bit of art in setting the constants for these election timers. There's some sort of competing requirements you might want to fulfill. Um, So one obvious requirement is that the election timer has to be at least as long as the expected interval between heartbeats.
[1:00:48] This is pretty obvious that the leader sends out heartbeats every 100 milliseconds you better make sure, you know, there's no point in having the election timer anybody's election timer ever go off for 100 milliseconds. because then it will go off before we could even have expected a new append entry. So the lower limit is certainly the lower limit is one heartbeat interval. In fact, because the network may drop packets. You probably want to have the minimum election timer value be a couple of times the heartbeat interval. So for 100 millisecond heartbeats, you probably want to have the very shortest possible election timer be say, 300 milliseconds.
[1:01:25] three times the heartbeat interval. Um, So that's the sort of minimum is the... Um, See if the heartbeats are this frequent, you want the minimum to be a couple of times that or here. Um, so what about the maximum? You know, you're gonna presumably randomize uniformly over some range of times. You know, where should we set the-- kind of maximum. Thank you. that we're randomizing over. And there's a couple of...
[1:01:55] considerations here in a real system. um, you know, this maximum time, uh... affects how quickly the system can recover from failure because Remember, from the time at which the server fails, until the first election timer goes off, The whole system is frozen. There's no leader. You know, the client's requests are being thrown away because there's no leader. and we're not assigning a new leader even though you know Presumably these other servers are up.
[1:02:26] So the bigger we choose this maximum, the longer delay we're imposing on clients before recovery occurs. You know, whether that's important, depends on sort of how high performance we need this to be, and how often we think there will be, Failure. If failure's happening once a year, then who cares? Um, If we're expecting failures frequently, we may care very much. how long it takes to recover. Okay, so that's one consideration. The other consideration is that this gap That is the expected gap in time between the first timer going off and the second timer going off.
[1:03:03] Um, This gap really, in order to be useful, has to be longer than the time it takes for the candidate to assemble votes from everybody. That is... longer than the expected round trip time, the amount of time it takes to send an RPC and get the response. Yeah, maybe it takes 10 milliseconds. to send in RPC and get a response, get a response from, um, all the other servers. And if that's the case, we need to make maximum release long enough that there's pretty likely to be 10 milliseconds difference between the smallest random number and the next smallest random number.
[1:03:35] Um, Thank you. And for you, Um, the test code will get upset if you, uh, um Thank you. if you don't recover from a leader failure in a couple seconds. And so, just pragmatically, you need to tune this maximum down so that It's highly likely that. You'll be able to complete a leader election within a few seconds. That's not a very tight constraint.
[1:04:09] Any questions about the election timeouts? One tiny point is that, um, You want to... Choose new random timeouts. every time there's, every time you Every time I know-- resets its election timer. That is, Don't choose a random number when... server is first created and then reuse that same number over and over again. Because you make an unlucky choice that is You choose the same.
[1:04:39] one server happens by ill chance to choose the same random number as another server. That means that you're gonna have split votes over and over again. forever. So that's why you want to almost certainly choose a different, a new, a fresh random for the election timeout value every time You reset the timer. Thank you. All right, so, a final issue about leader election. Suppose we are in this situation where the old leader's partitioned.
[1:05:10] You know, the network cable is broken, and the old leader is sort of out there with a couple clients. and a minority of servers. There's a majority in the other half of the network, and the majority in the new half of the network elects a new leader. What about the old leader? Why won't the old leader... Thank you. cause incorrect execution. Thank you. Maybe it's Yeah, right there.
[1:05:56] That's how that's gonna... - I'm glad to. Bye. and that's all done. God. Thank you. Yeah. two potential problems. Or one sort of non-problem is that if there's a leader off in another partition and it doesn't have a majority, then the next time a client sends it a request, Um, that leader that, you know, an abarctuation with a minority, yeah, it'll send out append entries, but Because it's in the minority partition, it won't be able to get responses back from a majority of the servers, including itself. And so it will never...
[1:06:34] commit the operation, it'll never execute it. It'll never respond to the client. saying that it executed it either. And so that means that, yeah, an old server off in a different partition People may, clients may send a request, but they'll never get responses. um, So no client will be fooled into thinking that the, that old server executed anything for it. The other sort of more tricky issue, which actually I'll talk about in a few minutes, is the possibility that before a server fails, it sends out append entries to a subset.
[1:07:14] of the servers. and then crashes before making a commit decision. And that's a very interesting question, which um We'll probably spend a good 45 minutes talking about that. And so, actually, before I turn to the back, topic in general. more questions about leader election. Thank you. OK. um Okay, so how about the contents of the logs and how in particular how a newly elected leader possibly picking up the pieces after an awkward crash of the previous leader, How does a newly elected leader sort out the possibly divergent logs on the different replicas?
[1:08:01] in order to restore sort of consistent state in the system. Um, All right, so the first question is, What can things, this whole topic is really only interesting after a server crashes, right? If the server stays up, then relatively few things can go wrong. If we have a server that's up and has a majority, you know, during the period of time when it's up and has a majority, Um, just tells the followers what the log should look like.
[1:08:36] And the followers are not allowed to disagree. They're required to accept. They just do by the rules of figure two if they've been more or less keeping up. You know, they just take whatever the leader sends them, and append entries, and append it to the log, and obey commit messages, and execute. Hardly anything to go wrong. The things that go wrong in rap go wrong when the old leader crashes sort of midway through you know, sending out messages or a new leader crashes, you know, sort of just after it's been elected, Um... before it's done anything very useful.
[1:09:08] So, one thing we're very interested in is what can the logs look like after some sequence of crashes? Um... Okay. Here's an example. So then we have three servers. Thank you. Thank you. Um, And the way I'm gonna draw out these diagrams, 'cause we're gonna be looking at a lot of, sort of situations where the logs look like this, and we're going to be wondering, is that possible, and what happens if they do look like that? So, my notation's going to be, I'm going to write out log entries for, um, Each of the servers sort of aligned to indicate slots.
[1:09:46] corresponding slots in the log. And the values I'm gonna write here are the term numbers rather than client operations. I'm going to, you know, this is slot one, this is slot two. Um, Everybody saw a command from term three in slot one, Server 2 and Server 3 saw command from also from term three, In the second slot, the server one has nothing there at all. Um, And so the question for this, like the very first question is, can this arrive?
[1:10:18] Could this... set up Arise and how? Oh. How? Thank you. Yeah, so . Thank you. So.
[1:11:03] So maybe server three was the leader for, just repeating what you said, maybe server three is the leader for term three. It got a command that sent out to everybody. Everybody received the dependent as the log. And then I got a server three, Got a second request from a client. and Maybe it sent it to all three servers, but the message got lost on the way to server one, or maybe server one was down at the time or something, and so only server two Well, the leader always appends new commands to its log before it sends out append entries. Um, and maybe the append entry RPC only got to server two. So this situation, you know, It's like the simplest situation in which actually the logs are now different.
[1:11:38] And we know how it could possibly... arise. And so if server three, which is the leader, should crash now, you know, the next server they're going to need to make sure server one Well, First of all, If server 3 crashes, or we get an election and some other leader is chosen, You know, two things have to happen. The new leader... It's got to recognize that This. Um, a command could have committed. It's not allowed to throw it away. and it needs to make sure server one fills in this blank here with indeed this very same command that everybody else had in that slot.
[1:12:15] Um, Thank you. All right, so after a crash, somebody, you know, a server suppose, another way this can come up is server three might have sent out the append entries to server two, but then crashed before sending the append entries to server three. So if we're electing a new leader, it could be because We got a crash. before the message was sent. All right, here's another scenario to think about. Um, Three servers again. Thank you. Thank you. Thank you. Um, Now I'm going to number the slots in the lawn.
[1:12:47] So we can refer to them. Um, We've got slot 10, 11, 12. Thank you. 13. Again. That's... Thank you. same setup except Now we have in slot 12, we have Server 2 as a command from term four and server three has a term command from term five. Thank you. Thank you. So-- Before we analyze these to figure out what would happen, what would a server do if it saw this, we need to ask Could this even occur?
[1:13:25] Sometimes the answer to the question, oh geez, what would happen if this configuration arose? Sometimes the answer is, It cannot arise, so we do not have to worry about it. um So the question is, Could this arise and how? Yeah. say no, because we have a lot of . Okay. Thank you. Thank you. Um, All right.
[1:14:00] And any-- All right. Thank you. The first situation happens. Amen. watching. friends. - Now, Troy. Bye. Roger. Thank you. What? Uh... Right, sensei.
[1:14:32] guys. Thank you. - Oh my God. All right. back up. Yeah. How far? So let me just repeat that. Brief. we know this configuration can arise, and so the way we can then get a four and a five here is, Let's suppose in the next leader election, server 2 is elected leader.
[1:15:09] Now for term four. Select the leader. You get a request from a client, it appends it to its own log and crashes. So now we have this. Right, we need a new election because the leader just crashed. Now, in this election, Thank you. And so now we have to ask whether who could be elected, or we have to keep in the back of our heads, oh gosh, who could be elected? Um, so we're gonna claim server three could be elected. The reason why it could be elected is because it only needs request vote responses from a majority. That majority is server one and server three.
[1:15:41] You know, there's no problem, no conflict between these two logs. So server three can be elected for term five, get a request from a client. appended to its own log and crash. And that's how you get this. uh, this configuration. So you need to be able to-- Bye. to work through these things. in order to get to the stage of saying, yes, this could happen, and therefore, Raft must do something sensible, as opposed to, it cannot happen. Because some things can't happen.
[1:16:12] Um, Thank you. All right, so... Um, So what can happen now? We know this can occur. Hopefully we can convince ourselves that Raft actually does something sensible. Now, As for the range of things, before we talk about what Raph would actually do. We need to have some sense of what would be an acceptable outcome.
[1:16:47] Right? and just eyeballing this, Um, We know that The command in slot 10, since it's known by all All the replicas, it could have been committed. so we cannot throw it away. Similarly, the command in slot 11, since it's in a majority of the replicas, it could, for all we know, have been committed, so we can't throw it away. The command in slot 12, however, neither of them could possibly have been committed. So we're entitled. We don't know, we haven't Looked at what Raft will actually do, but Raft is entitled to drop both of the even though it is not entitled to drop in either of the commands in the 10 or 11.
[1:17:26] Um, This is an entitled drop. It's not required. to drop either one of them. And we know it certainly must drop one, at least one, because You have to have identical log contents in the end. This could have been committed. the We can't tell by looking at the logs. exactly how far the leader got before crashing. So one possibility, is that for this command or even this command, One possibility is that a leader send out the append messages with a new command and then immediately crashed.
[1:18:04] So it never got any response back because it crashed. So the old leader did not know if it was committed. And if it didn't get a response back, That means it didn't execute it and it didn't send out but, you know, it didn't send out the incremented commit index. And so maybe the replicas didn't execute it either. So it's actually possible that this wasn't committed. So, Even though Raft doesn't know, Um, It could be legal for Raft Thank you.
[1:18:36] If RAP knew more than it does know, It might be legal. to drop this log entry, because it might not have been committed. but because on the evidence, There's no way to disprove it was committed based on this evidence. It could have been committed. and Raft can't prove it wasn't. So it must treat it as committed. Right, because the leader might have received it, might have crashed just after receiving the append entry replies. and replying to the client. So just looking at this, we can't rule out the possibility either possibility.
[1:19:11] that the leader responded to the client, in which case we cannot throw away this entry because a client knows about it. Or the possibility the leader never did, and yeah, we could. you know So we have to assume that. It was committed. Question? . um, Uh...
[1:19:46] No, there's no--I mean, in this situation, maybe the server crashed before getting the All right, let's continue this. on Thursday.
Abrir no ambiente de trabalho do Vidleaf
Pesquise a transcrição, selecione linhas, copie citações com carimbos de data/hora, traduza.
Atribuição
"Aula 6: Tolerância a Falhas: Raft (1)" por MIT 6.824: Sistemas Distribuídos (https://www.youtube.com/@6.824), licenciado sob CC BY 3.0 (https://creativecommons.org/licenses/by/3.0/). Vídeo original: https://www.youtube.com/watch?v=64Zp3tzNbpE. Esta página é uma transcrição em texto do vídeo com quebras de parágrafo e carimbos de tempo adicionados; o criador não é afiliado e não endossa a Vidleaf. A Vidleaf adicionou pontuação por IA e um resumo gerado por IA; o texto original permanece disponível nesta página.
Você é o criador ou detentor de direitos? Solicite uma correção ou remoção: copyright@vidleaf.app (veja Sobre estas páginas).
Última atualização
Todas as páginas de transcriçãoFerramenta de transcrição do YouTube