Cloud Spanner: TrueTime e consistência externa

Benefícios do TrueTime para o Cloud Spanner

O TrueTime é um relógio de distribuição altamente disponível fornecido para aplicativos em todos os servidores do Google1. Ele permite que os aplicativos gerem carimbos de data/hora crescentes monotonicamente: um aplicativo pode calcular um carimbo de data/hora T que tem garantia de que seja maior que qualquer carimbo de data/hora T' se T' for gerado antes de T começar a ser gerado. Essa garantia é válida em todos os servidores e para todos os carimbos de data/hora.

Esse recurso do TrueTime é usado pelo Cloud Spanner para atribuir carimbos de data/hora às transações. Especificamente, cada transação recebe um carimbo de data/hora que reflete o instante em que o Cloud Spanner considera que ela ocorreu. Como o Cloud Spanner usa o controle de simultaneidade de várias versões, a garantia de ordenação nos carimbos de data/hora permite que os clientes do Cloud Spanner realizem leituras consistentes em um banco de dados inteiro (mesmo em várias regiões do Cloud) sem bloquear gravações.

Consistência externa

O Cloud Spanner oferece aos clientes as garantias de controle de simultaneidade mais rigorosas para transações, que é chamada de consistência externa2. Sob a consistência externa, o sistema se comporta como se todas as transações fossem executadas sequencialmente, mesmo que na verdade o Cloud Spanner as execute em vários servidores (e possivelmente em vários datacenters) para maior desempenho e disponibilidade. Além disso, se uma transação é concluída antes de outra começar a confirmação, o sistema garante que os clientes nunca possam ver um estado que inclua o efeito da segunda transação, mas não da primeira. De maneira intuitiva, o Cloud Spanner é semanticamente indistinguível de um banco de dados de uma única máquina. Além de fornecer garantias tão fortes, o Cloud Spanner permite que os aplicativos alcancem um desempenho comparável aos bancos de dados que oferecem garantias mais fracas em troca de um desempenho superior. Por exemplo, como os bancos de dados compatíveis com isolamento de instantâneos, o Cloud Spanner permite que as gravações prossigam sem serem bloqueadas por transações somente leitura, mas sem exibir as anomalias que o isolamento de instantâneos permite.

A consistência externa simplifica muito o desenvolvimento de aplicativos. Por exemplo, imagine que você criou um aplicativo bancário no Cloud Spanner e um dos clientes começa com US$ 50 na conta corrente e US$ 50 na conta poupança. Seu aplicativo então começa um fluxo de trabalho no qual ele primeiro confirma uma transação T1 para depositar US$ 200 na conta poupança e, em seguida, emite uma segunda transação T2 para debitar US$ 150 da conta corrente. Além disso, imagine que, no fim do dia, os saldos negativos em uma conta sejam cobertos automaticamente por outras contas, e um cliente sofre uma penalidade se o saldo total em todas as contas for negativo a qualquer momento durante esse dia. A consistência externa garante que, como a T2 começa a confirmar após a T1 terminar, todos os leitores do banco de dados observarão que a T1 de depósito ocorreu antes da T2 de débito. Dito de outra forma, a consistência externa garante que ninguém jamais veja um estado em que a T2 tenha ocorrido antes da T1. Em outras palavras, o débito nunca causará uma penalidade por fundos insuficientes.

Um banco de dados tradicional que usa bloqueio rígido de duas fases oferece consistência externa. Infelizmente, nesse sistema, toda vez que o aplicativo quer ler os dados mais atuais (o que chamamos de "leitura forte"), o sistema adquire um bloqueio de leitura nos dados, que bloqueia as gravações nos dados que estão sendo lidos.

Carimbos de data/hora e controle de simultaneidade de várias versões (MVCC)

Para ler sem bloquear gravações, o Cloud Spanner e muitos outros sistemas de banco de dados mantêm várias versões de dados imutáveis (muitas vezes chamadas de controle de simultaneidade de várias versões). Uma gravação cria uma nova versão imutável, cujo carimbo de data/hora é o da transação da gravação. Uma "leitura de instantâneo" em um carimbo de data/hora retorna o valor da versão mais recente antes desse carimbo de data/hora e não precisa bloquear as gravações. Portanto, é importante que os carimbos de data/hora atribuídos às versões sejam consistentes com a ordem em que as transações podem ser observadas para confirmar. Chamamos essa propriedade de "processo do carimbo de data/hora apropriado". Observe que a existência de um processo do carimbo de data/hora apropriado é equivalente à consistência externa.

Para ver por que o processo do carimbo de data/hora apropriado é importante, pense no exemplo bancário da seção anterior. Sem o processo do carimbo de data/hora apropriado, a T2 poderia ser atribuída a um carimbo de data/hora anterior ao atribuído à T1. Por exemplo: se um sistema hipotético usasse horários locais em vez do TrueTime e o horário do servidor que processa a T2 estivesse ligeiramente atrasado. Uma leitura de instantâneo poderia refletir o débito da T2, mas não o depósito da T1, mesmo que o cliente tenha visto o depósito finalizado antes de iniciar o débito.

Conseguir o carimbo de data/hora apropriado é trivial para um banco de dados de uma única máquina. Por exemplo: você pode apenas atribuir carimbos de data/hora de um contador global e crescente monotonicamente. Conseguir isso em um sistema amplamente distribuído, como o Cloud Spanner, em que servidores de todo o mundo precisam atribuir carimbos de data/hora, é muito mais difícil de fazer de maneira eficiente.

O Cloud Spanner depende do TrueTime para gerar carimbos de data/hora monotonicamente crescentes. O Cloud Spanner usa esses carimbos de data/hora de duas maneiras. Primeiro, ele os usa como carimbos de data/hora apropriados para transações de gravação sem a necessidade de comunicação global. Em segundo lugar, ele os usa como carimbos de data/hora para leituras fortes, o que permite que elas sejam executadas em uma rodada de comunicação e até mesmo que elas abranjam vários servidores.

Perguntas frequentes

Quais garantias de consistência são oferecidas pelo Cloud Spanner?

O Cloud Spanner oferece consistência externa, que é a propriedade de consistência mais rigorosa para sistemas de processamento de transações. Todas as transações no Cloud Spanner satisfazem essa propriedade de consistência, não apenas aquelas dentro de uma partição. A consistência externa indica que o Cloud Spanner executa transações de maneira indistinguível de um sistema em que as transações são executadas em série e, além disso, que a ordem serial é consistente com a ordem em que as transações podem ser observadas para confirmação. Como os carimbos de data/hora gerados para as transações correspondem à ordem serial, se qualquer cliente que vir uma transação T2 começar a confirmar após outra transação T1 terminar, o sistema atribuirá um carimbo de data/hora para T2 que é maior do que o carimbo de data/hora de T1.

O Cloud Spanner oferece capacidade de linearização?

Sim. Na verdade, o Cloud Spanner oferece consistência externa, que é uma propriedade mais forte do que a capacidade de linearização, porque ela não diz nada sobre o comportamento das transações. A capacidade de linearização é uma propriedade de objetos simultâneos que são compatíveis com operações de leitura e gravação atômicas. Em um banco de dados, um "objeto" normalmente seria uma única linha ou mesmo uma única célula. A consistência externa é uma propriedade de sistemas de processamento de transações em que os clientes sintetizam dinamicamente transações que contêm várias operações de leitura e gravação em objetos arbitrários. A capacidade de linearização pode ser vista como um caso especial de consistência externa em que uma transação só pode conter uma única operação de leitura ou gravação em um único objeto.

O Cloud Spanner oferece capacidade de serialização?

Sim. Na verdade, o Cloud Spanner oferece consistência externa, que é uma propriedade mais estrita do que a capacidade de serialização. Um sistema de processamento de transações é serializável se executa transações de maneira indistinguível de um sistema em que as transações são executadas em série. O Cloud Spanner também garante que a ordem serial seja consistente com a ordem em que as transações possam ser observadas para confirmação.

Pense novamente no exemplo bancário usado anteriormente. Em um sistema que oferece capacidade de serialização, mas não consistência externa, mesmo que o cliente tenha realizado a T1 e a T2 sequencialmente, o sistema poderá reordená-los, o que poderia fazer com que o débito resultasse em uma penalidade por fundos insuficientes.

O Cloud Spanner oferece consistência forte?

Sim. Na verdade, o Cloud Spanner oferece consistência externa, que é uma propriedade mais forte do que a consistência forte. O modo padrão para leituras no Cloud Spanner é "forte", o que garante que elas observam os efeitos de todas as transações que foram confirmadas antes do início da operação, independentemente de qual réplica recebe a leitura.

Qual a diferença entre consistência forte e consistência externa?

Um protocolo de replicação exibe "consistência forte" se os objetos replicados são linearizáveis. Como a capacidade de linearização, a "forte consistência" é mais fraca que a "consistência externa", porque não diz nada sobre o comportamento das transações.

O Cloud Spanner oferece consistência eventual (ou lenta)?

O Cloud Spanner oferece consistência externa, que é uma propriedade muito mais forte do que a consistência eventual. A consistência eventual tem garantias mais fracas em troca de maior desempenho. Ela é problemática porque os leitores podem observar o banco de dados em um estado em que nunca foi verdadeiro. Por exemplo: uma leitura pode observar um estado em que a transação B foi confirmada, mas na transação A não foi, mesmo que a A tenha acontecido antes da B. O Cloud Spanner fornece leituras desatualizadas, que oferecem benefícios de desempenho semelhantes à consistência eventual, mas com garantias de consistência muito mais fortes. Uma leitura desatualizada retorna dados de um carimbo de data/hora "antigo", que não pode bloquear as gravações porque as versões antigas dos dados são imutáveis.

Leitura adicional

Observações

  • 1J. C. Corbett, J. Dean, M. Epstein, A. Fikes, C. Frost, J. Furman, S. Ghemawat, A. Gubarev, C. Heiser, P. Hochschild, W. Hsieh, S. Kanthak, E. Kogan, H. Li, A. Lloyd, S. Melnik, D. Mwaura, D. Nagle, S. Quinlan, R. Rao, L. Rolig, Y. Saito, M. Szymaniak, C. Taylor, R. Wang e D. Woodford. Spanner: Google's Globally-Distributed Database. In Tenth USENIX Symposium on Operating Systems Design and Implementation (OSDI 12), pp. 261–264, Hollywood, CA, outubro de 2012.
  • 2Gifford, D. K. Information Storage in a Decentralized Computer System. Tese de doutorado, Universidade de Stanford, 1981.
  • Esta página foi útil? Conte sua opinião sobre:

    Enviar comentários sobre…

    Documentação do Cloud Spanner