Comecei a analisar abordagens para sincronização de dados entre um conjunto de pares. Os pares devem poder trabalhar de maneira desconectada e sincronizar juntos para mesclar suas alterações locais.
Os pares devem poder mesclar atualizações locais com uma "mesclagem de três maneiras" . Portanto, na sincronização, os pares devem saber quais fatos são mais recentes, mas onde não há uma ordem estrita, eles devem ser capazes de mesclar os fatos com base na raiz comum.
Quando pares independentes fazem alterações, eles podem "marcá-los" com um "relógio". Uso os termos "relógio" e "carimbo de hora", mas não estou querendo dizer um relógio de parede. Quero dizer algum tipo de ordenação parcial de eventos que torna clara a causalidade. É a relação "aconteceu antes" entre os eventos que forma um gráfico acíclico direcionado (DAG).
Parece que a maneira "usual" de criar essa ordem parcial é usando um relógio de vetor . Estes podem se tornar muito grandes, no entanto. Desenvolvimentos mais recentes, como relógios de árvore com intervalo, fornecem armazenamento mais compacto de registros de data e hora.
O que não estou claro é por que os protocolos de sincronização aparentemente não "simplesmente" armazenam o DAG explicitamente. (Ou eles?)
Os pares podem criar um carimbo de data / hora independentemente, gerando aleatoriamente um UUID (ou por outros meios, como <peer-name> + <local-monotonically-increasing-counter>
). A ordem desse carimbo de data e hora é totalmente clara para esse par.
Quando dois pares se sincronizam, eles podem concordar com um novo carimbo de data / hora. Novamente, a ordem desse carimbo de data e hora é clara para os dois pares.
Agora existe um requisito para passar o ocorrido antes do DAG entre pares, mas os requisitos de armazenamento e largura de banda são pequenos. Pontos no tempo são vértices gráficos. Como tal, eles têm 1 ou 2 arestas de entrada (1 para um evento em um cliente e 2 para uma sincronização entre clientes). Isso é limitado e independente do número de pares na rede.
Para usar um ponto no tempo individual, é necessário o gráfico dos pontos no tempo que levam a isso. No entanto, tanto quanto eu posso ver, qualquer par que é capaz de conhecer um ponto no tempo (ele próprio o gerou, ou o gerou com outro par, ou foi informado por outro par ao sincronizar com ele) também teve uma oportunidade de conhecer a história que antecedeu esse momento. Eu acho que provavelmente há uma prova indutiva para isso.
Dado que armazenar e sincronizar o DAG parece explicitamente simples: isso é usado na prática? Caso contrário, por que os relógios vetoriais são preferidos?
Notas
Pessoa para pessoa
Prefiro uma solução ponto a ponto do que uma solução de servidor cliente.
A provável topologia final será que muitos clientes se conectem a um grupo muito menor de servidores que se replicam entre si. No entanto, seria bom ter uma solução geral que suporte essa topologia específica, em vez de uma solução que exija essa topologia específica.
fonte
Respostas:
Até onde eu sei, sistemas de controle de versão como Git e Mercurial usam a abordagem DAG em vez de relógios vetoriais.
fonte
Dê uma olhada no problema de consenso . Dependendo dos requisitos da sua tarefa (quantos dados você possui, quantos nós de sincronização, quantas vezes etc.), as soluções existentes para esse problema (como "Raft") podem ser adequadas para o seu caso.
Outra abordagem (talvez tangencial) para esse problema é projetar um CRDT .
fonte