O Datastore oferece elevada disponibilidade, escalabilidade e durabilidade através da distribuição de dados em várias máquinas e da utilização da replicação síncrona numa vasta área geográfica. No entanto, existe uma compensação neste design, que é o facto de a taxa de transferência de gravação para qualquer grupo de entidades estar limitada a cerca de um commit por segundo, e existem limitações nas consultas ou transações que abrangem vários grupos de entidades. Esta página descreve estas limitações com mais detalhe e aborda as práticas recomendadas para estruturar os seus dados de forma a suportar uma forte consistência, ao mesmo tempo que cumpre os requisitos de débito de escrita da sua aplicação.
As leituras fortemente consistentes devolvem sempre os dados atuais e, se forem realizadas numa transação, parecem provir de um único instantâneo consistente. No entanto, as consultas têm de especificar um filtro de antepassados para serem fortemente consistentes ou participarem numa transação, e as transações podem envolver, no máximo, 25 grupos de entidades. As leituras eventualmente consistentes não têm essas limitações e são adequadas em muitos casos. A utilização de leituras eventualmente consistentes pode permitir-lhe distribuir os seus dados por um número maior de grupos de entidades, o que lhe permite obter um maior débito de gravação executando confirmações em paralelo nos diferentes grupos de entidades. No entanto, tem de compreender as caraterísticas das leituras eventualmente consistentes para determinar se são adequadas para a sua aplicação:
- Os resultados destas leituras podem não refletir as transações mais recentes. Isto pode ocorrer porque estas leituras não garantem que a réplica em que estão a ser executadas está atualizada. Em alternativa, usam os dados disponíveis nessa réplica no momento da execução da consulta. A latência de replicação é quase sempre inferior a alguns segundos.
- Uma transação comprometida que abrangeu várias entidades pode parecer ter sido aplicada a algumas das entidades e não a outras. No entanto, tenha em atenção que uma transação nunca vai parecer ter sido parcialmente aplicada numa única entidade.
- Os resultados da consulta podem incluir entidades que não deveriam ter sido incluídas de acordo com os critérios de filtro e podem excluir entidades que deveriam ter sido incluídas. Isto pode ocorrer porque os índices podem ser lidos numa versão diferente da versão em que a própria entidade é lida.
Para compreender como estruturar os seus dados para uma forte consistência, compare duas abordagens diferentes para uma aplicação de livro de visitas simples. A primeira abordagem cria uma nova entidade raiz para cada entidade criada:
Em seguida, consulta o tipo de entidade Greeting
para as dez saudações mais recentes.
No entanto, uma vez que está a usar uma consulta não descendente, a réplica usada para executar a consulta neste esquema pode não ter visto a nova saudação no momento em que a consulta é executada. No entanto, quase todas as escritas vão estar disponíveis para consultas de não antepassados alguns segundos após a confirmação. Para muitas aplicações, uma solução que forneça os resultados de uma consulta não ancestral no contexto das alterações do utilizador atual é geralmente suficiente para tornar essas latências de replicação completamente aceitáveis.
Se a consistência forte for importante para a sua aplicação, uma abordagem alternativa é escrever entidades com um caminho de antepassado que identifique a mesma entidade raiz em todas as entidades que têm de ser lidas numa única consulta de antepassado fortemente consistente:
Em seguida, pode executar uma consulta de antepassados fortemente consistente no grupo de entidades identificado pela entidade raiz comum:
Esta abordagem alcança uma forte consistência escrevendo num único grupo de entidades por livro de visitas, mas também limita as alterações ao livro de visitas a não mais de 1 escrita por segundo (o limite suportado para grupos de entidades). Se a sua aplicação tiver provavelmente uma utilização de escrita mais intensa, pode ter de considerar a utilização de outros meios: por exemplo, pode colocar publicações recentes num memcache com uma data de validade e apresentar uma combinação de publicações recentes do memcache e do Datastore, ou pode colocá-las em cache num cookie, colocar algum estado no URL ou algo completamente diferente. O objetivo é encontrar uma solução de colocação em cache que forneça os dados do utilizador atual durante o período em que o utilizador está a publicar na sua aplicação. Lembre-se de que, se fizer um get, uma consulta de antepassados ou qualquer operação numa transação, verá sempre os dados escritos mais recentemente.