Conceitos
Relaxed consistency semantics
Intuição
Imagine um quadro de avisos compartilhado onde várias pessoas podem colar recados ao mesmo tempo. Se só uma pessoa cola um recado por vez, todo mundo que olhar o quadro depois vê exatamente aquele recado, inteiro e legível. Mas se duas pessoas tentam colar recados na mesma hora, no mesmo espaço, o resultado pode virar uma mistura ilegível dos dois — ainda assim, todo mundo que olhar depois vê a MESMA mistura, só que ninguém consegue dizer com certeza o que cada um escreveu. Essa é a troca que o GFS aceita: em vez de garantir sempre um recado limpo, ele garante que pelo menos todo mundo enxerga a mesma coisa.
Como funciona
Depois de uma sequência de mutações bem-sucedidas, o GFS distingue duas garantias fracas em vez de uma consistência forte tradicional. Uma região é 'definida' (defined) quando foi escrita por uma única mutação que teve sucesso sem interferência de escritores concorrentes — nesse caso todos os clientes veem exatamente os mesmos dados, refletindo aquela mutação por completo. Quando múltiplos escritores concorrem pela mesma região, o resultado pode ficar apenas 'consistente' (consistent): todos os clientes ainda veem os mesmos bytes, mas esses bytes podem ser uma mistura imprevisível dos dados dos escritores concorrentes — 'undefined'. Uma mutação que falha pode deixar a região inconsistente, com réplicas de chunk diferentes contendo dados diferentes entre si. Para tornar isso operável na prática, o GFS oferece uma garantia mais forte só para um padrão específico de escrita: record append, no qual o cliente não escolhe o offset — o próprio GFS escolhe um offset e anexa o registro ali de forma atômica, pelo menos uma vez. Isso favorece múltiplos produtores concorrentes escrevendo no mesmo arquivo, ao custo de permitir registros duplicados ou padding ocasional, que as aplicações precisam tolerar (por exemplo, embutindo checksums ou identificadores únicos em cada registro para detectar e pular duplicatas).
Na prática
Os autores aceitaram esse contrato mais fraco deliberadamente, julgando que a maioria das aplicações — co-desenhadas junto com o próprio sistema de arquivos, como um job de MapReduce que faz muitos workers anexarem resultados a um único arquivo de saída — conseguiria conviver com ele em troca de evitar o custo de coordenação que uma garantia forte exigiria naquela escala. Esse é o tipo de trade-off que você assume quando controla as duas pontas (sistema e aplicação) e prioriza throughput e simplicidade de implementação sobre uma semântica de consistência limpa e previsível.
Use em um desenho
Pratique na escola de System Design os casos que dependem deste conceito.