Estructurar los datos para lograr una coherencia sólida

Cloud Datastore proporciona alta disponibilidad, escalabilidad y durabilidad mediante la distribución de datos en muchas máquinas y el uso de una replicación síncrona sin instancia maestra en un área geográfica amplia. Sin embargo, este diseño tiene la desventaja de que la capacidad de procesamiento de las operaciones de escritura de cualquier grupo de entidad está limitado a aproximadamente una confirmación por segundo, y también hay limitaciones para las consultas o las transacciones que pueden alcanzar varios grupos de entidades. En esta página, se describen esas limitaciones en mayor profundidad y se analizan las recomendaciones para estructurar los datos a fin de lograr una coherencia sólida y cumplir con los requisitos de rendimiento de escritura de la aplicación.

Las lecturas de coherencia sólida siempre muestran datos actuales y, si se realizan dentro de una transacción, parecerán provenir de una única instantánea coherente. Sin embargo, las consultas deben especificar un filtro principal para tener coherencia sólida o participar en una transacción, y las transacciones pueden involucrar un máximo de 25 grupos de entidades. Las lecturas con coherencia eventual no tienen esas limitaciones y son adecuadas en muchos casos. Utilizar lecturas con coherencia eventual puede permitirte distribuir tus datos entre más grupos de entidades, lo que hace posible obtener una mayor capacidad de procesamiento de escritura a través de la ejecución de confirmaciones en paralelo en los distintos grupos de entidades. Sin embargo, debes comprender las características de las lecturas con coherencia eventual a fin de determinar si son adecuadas para tu aplicación:

  • Los resultados de esas lecturas pueden no reflejar las transacciones más actuales. Esto puede suceder porque esas lecturas no se aseguran de que la réplica sobre la que se ejecutan esté actualizada. En cambio, utilizan cualquier dato disponible en esa réplica cuando se ejecuta la consulta. La latencia de replicación es casi siempre inferior a unos pocos segundos.
  • Puede parecer que una transacción confirmada en múltiples entidades se aplicó solo a algunas de ellas. Sin embargo, nunca parecerá que una transacción se aplicó de manera parcial dentro de una sola entidad.
  • Los resultados de una consulta pueden contener entidades que no deberían haberse incluido según los criterios del filtro y es posible que se excluyan entidades que sí deberían haberse incluido. Esto puede ocurrir porque los índices pueden leerse en una versión diferente de la que se lee en la entidad.

A fin de comprender cómo estructurar tus datos para una coherencia sólida, compara dos enfoques diferentes del ejercicio del Instructivo del libro de visitas de App Engine. El primer enfoque crea una nueva entidad raíz para cada saludo:

Java 7

protected Entity createGreeting(
    DatastoreService datastore, User user, Date date, String content) {
  // No parent key specified, so Greeting is a root entity.
  Entity greeting = new Entity("Greeting");
  greeting.setProperty("user", user);
  greeting.setProperty("date", date);
  greeting.setProperty("content", content);

  datastore.put(greeting);
  return greeting;
}
g := Greeting{ /* ... */ }
key := datastore.NewIncompleteKey(ctx, "Greeting", nil)

A continuación, consulta los similares de entidad Greeting para obtener los diez saludos más recientes.

q := datastore.NewQuery("Greeting").Order("-Date").Limit(10)

Sin embargo, debido a que estás usando una consulta no principal, es posible que la réplica utilizada para realizar la consulta en este esquema no haya visto el nuevo saludo en el momento en que se ejecuta la consulta. No obstante, casi todas las escrituras estarán disponibles para consultas no principales pocos segundos después de su confirmación. En el caso de muchas aplicaciones, una solución que proporcione los resultados de una consulta no principal en el contexto de los cambios propios del usuario actual será generalmente suficiente para hacer que las latencias de replicación sean completamente aceptables.

Si es importante que tu aplicación tenga coherencia sólida, un enfoque alternativo es escribir entidades con una ruta de acceso principal que identifique la misma entidad raíz en todas las entidades que deben leerse en una consulta principal única con coherencia sólida:

g := Greeting{ /* ... */ }
key := datastore.NewIncompleteKey(ctx, "Greeting", guestbookKey(ctx))

Luego podrás realizar una consulta principal con coherencia sólida dentro del grupo de entidades identificado por la entidad raíz común.

q := datastore.NewQuery("Greeting").Ancestor(guestbookKey(ctx)).Order("-Date").Limit(10)

Este enfoque logra una coherencia sólida por medio de la escritura en un solo grupo de entidades por libro de visitas, pero también limita los cambios en el libro de visitas a no más de 1 escritura por segundo (el límite admitido para los grupos de entidades). Si es probable que tu aplicación tenga un uso de escritura más intenso, podría ser conveniente que uses otros medios: Por ejemplo, puedes colocar publicaciones recientes en un sistema Memcache con vencimiento y mostrar una mezcla de publicaciones recientes de Memcache y Cloud Datastore, o podrías almacenarlas en caché en una cookie, poner algún estado en la URL, o algo completamente distinto. El objetivo es encontrar una solución de almacenamiento en caché que le brinde datos al usuario actual durante el período en el que el usuario publica en tu aplicación. Recuerda que si realizas una operación get, una consulta principal o cualquier operación dentro de una transacción, siempre verás los datos escritos más recientemente.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Entorno estándar de App Engine para Go