Pontos Principais
-
A latência é o maior motivo pelo qual um banco de dados padrão não é adequado para as arquiteturas na computação de borda;
-
Os CRDTs, ou tipos de dados replicados sem conflito (conflict-free replicated data types), são um estado primitivo relativamente novo que fornece uma maneira de contornar grande parte da complexidade quando falamos de consistência;
-
Semelhante a como os CRDTs eliminam classes inteiras de complexidade relacionadas ao tratamento de falhas, o uso de chamadas de procedimento remoto síncronas para sincronização elimina classes inteiras de complexidade relacionadas à teoria das filas;
-
Sistemas RDBMS padrões e técnicas de sistemas distribuídos comuns são incrivelmente úteis e produtivas até uma certa escala porém, posterior a isso, a complexidade se torna injustificável.
Na QCon Londres de 2020, Peter Bourgon, da Fastly, deu uma palestra que foi bem recebida sobre os desafios da gestão dos estados dos sistemas distribuídos. Especificamente, discutiu sobre como é um modelo de arquitetura e comunicação para uma plataforma de borda em escala global.
Foi uma palestra que abordou uma variedade de temas. Existe uma fonte central de verdade para os dados? Como os dados devem ser sincronizados no sistema? Qual é a estrutura de dados certa para armazenar o estado? O InfoQ conversou com Peter um pouco mais sobre algumas áreas que consideramos interessantes para nossos leitores.
InfoQ: Você acha que a "borda" é a próxima arquitetura amplamente adotada para nos sistemas modernos? Ou é um nicho importante, porém diminuto, adequado para um subconjunto específico de sistemas? Se sim, quais seriam estes subconjuntos?
Bourgon: Não acho que a "borda" seja uma arquitetura em si, eu diria que ela é um componente de uma arquitetura. Os usuários esperam que as aplicações sejam rápidas, e a velocidade da luz impõe algumas restrições físicas inevitáveis sobre como podemos atender a essas expectativas. Depois de um determinado momento, a única maneira de diminuir a latência e melhorar as experiências é movendo a aplicação, no todo ou em parte, fisicamente para mais próximo dos usuários. E as plataformas de borda são uma solução para fazermos isso.
É óbvio que nem todos os sistemas verão valor ao estender o estado e a lógica para fora do datacenter. Definitivamente, existe um trabalho de repensar, reformular, e re-arquitetar envolvido, e isso sempre é uma decisão da engenharia com relação a custos e benefícios. Mas, olhando para o futuro, acho que o papel da borda no design do sistema ficará maior e mais importante.
InfoQ: Você comentou na palestra que um "banco de dados padrão" não é adequado para os sistemas de borda com estado. Poderia explicar um pouco sobre o por que alguém não gostaria de um único banco de dados centralizado para um sistema na borda? Está ligado inteiramente com a latência?
Bourgon: Acho que a latência é o maior motivo. Se estamos estendendo o sistema para fora do datacenter em direção à borda, já presumimos que os custos dos dados irem e voltarem são muito altos. Os usuários experimentam esses custos com ativos estáticos, com lógica da aplicação e também com o estado, então, se as transações sempre voltam para a origem, não estamos aproveitando totalmente a arquitetura.
Mas há outro motivo, que está relacionado à consistência. Com um banco de dados centralizado, é relativamente fácil expressar transações como sendo a "verdade" global, lógica, coerente e absoluta. Como as partes do sistema não estão separadas por uma grande distância, podemos realizar a comunicação necessária para essa transação de maneira rápida e ficar dentro dos limites de latência. Mas se distribuir o estado pelo mundo, fazer uma transação tradicional torna-se algo proibitivo. É imperativo permitir que os usuários manipulem o estado localmente, sem estabelecer um consenso global, e isso significa optar por sistemas de dados não tradicionais, geralmente mais consistentes.
InfoQ: Na palestra, foi aprofundado os tipos de dados replicados sem conflito, conhecidos como CRDTs. Poderia explicar mais sobre isso, por que fazem sentido para uma arquitetura de borda com estado e como ou quais dados são armazenados?
Bourgon: Provavelmente, a parte mais difícil dos sistemas distribuídos é lidar com as falhas. Os computadores são mutáveis, as redes não são confiáveis, as topologias evoluem, e as falácias da computação distribuída são bem conhecidas, e o conhecimento delas tendem a dominar o esforço da engenharia de sistemas bem-sucedidos. E se o sistema está gerenciando o estado, as coisas ficam muito mais difíceis: manter um modelo de consistência útil para os usuários requer uma coordenação extremamente cuidadosa, com uma consistência forte, normalmente exigindo um esforço proporcional. Isso acarreta, cedo ou tarde, mais bugs e menos confiabilidade.
Os CRDTs, também conhecido como tipos de dados replicados sem conflito (conflict-free replicated data types), são um estado primitivo relativamente novo que permite contornar grande parte dessa complexidade. Penso neles como sendo tipos de dados cuidadosamente construídos, cada um combinado com um conjunto específico de operações. De maneira simplificada, se garantirmos que as operações sejam associativas, comutativas e idempotentes, os CRDTs permitem aplicá-los em qualquer ordem, inclusive quando estiverem duplicados, obtendo os mesmos resultados determinísticos no final. Dito de outra forma, os CRDTs possuem resolução de conflitos embutida, então não precisamos ter este trabalho na aplicação. Formalmente, exibem algo denominado forte consistência eventual.
Essa propriedade, per se, define que qualquer sistema construído com CRDTs pode ter gerenciamento de falhas padrões sem nenhum problema. Procure enviar as operações em qualquer ordem e sem nenhum tipo de coordenação aos nós que necessitam dessas informações. Se houver um problema, tente novamente mais tarde. Simples assim. Contanto que as operações consigam chegar ao seu destino, o sistema tem a garantia de estar correto. Ao escolher um estado primitivo mais inteligente, podemos construir um sistema muito mais simples e confiável.
Os CRDTs permitem muitos casos de uso interessantes, como a edição offline de documentos que pode ser sincronizada automaticamente. No contexto do estado de borda, eles permitem manter nas transações locais até o ponto de presença, para atender aos requisitos de latência, enquanto ainda podemos compartilhar o estado globalmente.
Claro que esses benefícios não vêm de graça. Nem sempre é fácil, ou óbvio, como modelar os dados como CRDTs. Operações aparentemente simples, como delete, podem ter CRDT equivalentes, terrivelmente complexos. Além disso, os detalhes às vezes confusos de várias versões paralelas de estado tendem a aparecer nas APIs dos sistemas, e as aplicações precisam se adaptar para lidar com elas, o que nem sempre é fácil. Mais importante, é avaliar que um único byte de estado lógico utilizável em um CRDT requer muito mais bytes de memória real, o que pode rapidamente tornar a economia desses sistemas inviável.
Como qualquer tecnologia focada para o uso produtivo, concessões, compensações, e otimizações de engenharia são necessários para tornar os CRDTs viáveis.
InfoQ: Foi comentado que chamadas síncronas para sincronização de estado podem ser a melhor opção do que chamadas assíncronas orientadas a eventos. Por qual motivo?
Bourgon: Este é um ponto secundário, mas importante, relacionado à implementação de sistemas distribuídos. É basicamente impossível confiar na segurança e confiabilidade de sistemas de grande escala como este sem ser capaz de executar o sistema sob teste determinístico ou simulação. E também é impossível simular um sistema, a menos que cada componente possa ser modelado como uma máquina de estado simples e determinística. Certamente é possível obter essas propriedades usando eventos assíncronos como o padrão de mensagens, mas a experiência me ensinou que é significativamente mais fácil com uma abordagem de estilo RPC síncrona. Semelhante a como os CRDTs eliminam classes inteiras de complexidade relacionadas ao tratamento de falhas, os RPCs síncronos eliminam classes inteiras de complexidade relacionadas à teoria das filas. Eles fornecem contrapressão automática, permitem que aproveitemos as vantagens das filas que já existem em várias camadas do sistema operacional e da pilha de rede e, por último mas não menos importante, tornam mais fácil construir componentes determinísticos.
InfoQ: A palestra foi finalizada dizendo que "rodadas de consenso, ou eleição de líder, ou bloqueios distribuídos ou transações distribuídas" são becos sem saída e que sistemas de grande porte usarão comunicação simples e, eventualmente, serão consistentes. Conte-nos mais sobre o motivo disso se tornar realidade.
Bourgon: Acho que toda a conquista tecnológica humana tem sido um exercício de criação, objetificação e extensão de abstrações. A capacidade humana de compreender e gerenciar a complexidade é limitada, pois tentando tornar as coisas possíveis, necessitamos usar abstrações para "isolar" os domínios de complexidade por trás dos modelos mais simples que podem ser facilmente compreendidos e desenvolvidos. Por exemplo, os desenvolvedores hoje não precisam saber como as interfaces de rede traduzem dados binários em sinais elétricos sobre cobre, ou frames Ethernet em binários, ou datagramas em frames Ethernet, e assim por diante. As abstrações do modelo OSI permitem que o desenvolvedor gaste o orçamento para lidar com complexidade em um nível muito mais alto. Basicamente, tudo isso resistiu ao teste do tempo, então acho que é um bom conjunto de abstrações.
Os desenvolvedores também confiaram na abstração de uma única verdade global para a camada de dados, essencialmente desde o primeiro banco de dados. É compreensível e produtivo, então faz sentido. Mas acredito que possamos fazer um paralelo com o modelo newtoniano em relação a física: funciona, até não funcionar mais. Em uma escala realmente grande, a física newtowniana não prevê o comportamento no mundo real, então temos que mudar para o modelo relativístico mais complexo. Da mesma forma, quando começamos a estender nossa camada de dados por grandes distâncias físicas, acredito que a abstração de uma única verdade global começa a não fazer tanto sentido. Um incrível esforço de engenharia é necessário para manter a ilusão de atomicidade, usando técnicas como as que listei. Em algum ponto, os desenvolvedores que trabalham dentro e ao redor dessa camada de abstração vão esgotar o orçamento da complexidade.
Os sistemas RDBMS típicos e técnicas de sistemas distribuídos comuns são incrivelmente úteis e produtivos até uma certa escala. Mas, além dessa escala, a complexidade necessária para sustentar a ilusão de atomicidade global torna-se não confiável, improdutiva e, em última análise, injustificável. Embora exista um custo inicial para pensar sobre vários universos paralelos de estado da aplicação, acredito que o preço compensa as ordens de magnitude mais complexas, ocultas na abstração alternativa e incompleta. E acredito que, eventualmente, vamos perceber que é a única maneira de construir sistemas distribuídos confiáveis e em grande escala.
De qualquer forma, isso não é exatamente um pensamento inovador. A natureza está cheia de sistemas incrivelmente complexos, cujos comportamentos são decorrentes de princípios e regras simples. Meu exemplo favorito é provavelmente como grupos de vagalumes conseguem sincronizar suas luzes. Nenhuma definição de líder ou rodadas de consenso estão envolvidas.
Sobre o entrevistado
Peter Bourgon atualmente lidera a pesquisa e o desenvolvimento de uma infraestrutura global para o estado de borda na Fastly, uma plataforma de CDN e nuvem de borda. É o autor do Go kit, o das ferramentas proeminentes para microservices em Go, além de vários sistemas distribuídos que evitam a coordenação em grande escala, incluindo Roshi (índice de fluxo) e OK Log (agregador de logs).