standard ndb google features engine compute change app google-app-engine google-cloud-datastore

google app engine - ndb - Datastore de replicación alta de App Engine



google cloud app engine dns (3)

Soy un principiante total de App Engine y quiero confirmar mi comprensión del almacén de datos de alta replicación.

La documentación dice que los grupos de entidades son una "unidad de coherencia" y que todos los datos son finalmente consistentes. En la misma línea, también dice que "las consultas entre los grupos de entidades pueden ser obsoletas".

¿Puede alguien proporcionar algunos ejemplos donde las consultas pueden ser "obsoletas"? ¿Está diciendo que podría potencialmente salvar una entidad sin un padre (es decir, su propio grupo), luego buscarla muy pronto y no encontrarla? ¿También implica que si quiero que los datos estén siempre al 100% actualizados, necesito guardarlos todos en el mismo grupo de entidades?

¿La solución común para esto es utilizar Memcache para almacenar en caché las entidades por un período de tiempo mayor que el tiempo promedio que los datos tardan en ser coherentes en todos los centros de datos? ¿Cuál es la latencia del estadio para eso?

Gracias


¿Está diciendo que podría potencialmente salvar una entidad sin un padre (es decir, su propio grupo), luego buscarla muy pronto y no encontrarla?

Correcto. Técnicamente, este también es el caso del almacén de datos Maestro-Esclavo habitual, ya que los índices se actualizan de forma asíncrona, pero en la práctica la ventana de tiempo en que eso podría suceder es tan increíblemente pequeña que nunca la ves.

Si por "consulta" quiere decir "hacer una obtención por clave", eso siempre devolverá resultados consistentes en cualquiera de las implementaciones.

¿También implica que si quiero que los datos estén siempre al 100% actualizados, necesito guardarlos todos en el mismo grupo de entidades?

Tendrá que definir lo que quiere decir con "100% actualizado" antes de que sea posible responder eso.

¿La solución común para esto es utilizar Memcache para almacenar en caché las entidades por un período de tiempo mayor que el tiempo promedio que los datos tardan en ser coherentes en todos los centros de datos?

No. Memcache es estrictamente para mejorar los tiempos de acceso; no deberías usarlo en ninguna situación en la que el desalojo del caché cause problemas.

Los robos consistentemente consistentes siempre están disponibles para usted si necesita garantizar que está viendo la última versión. Sin embargo, sin un ejemplo concreto de lo que intenta hacer, es difícil ofrecer una recomendación.


Después de migrar mi aplicación del Maestro / Esclavo al almacén de datos de Alta Replicación, debo decir que en la práctica, la consistencia final no es un problema para la mayoría de las aplicaciones.

Considere el ejemplo clásico de libro de visitas, donde put() una nueva Entidad de publicación de libro de visitas y luego consulta inmediatamente todas las publicaciones en el libro de visitas. Con el almacén de datos de alta replicación, no verá la nueva publicación aparecer en los resultados de la consulta hasta unos segundos más tarde (en Google I / O, los ingenieros de Google dijeron que el retraso era del orden de 2-5 segundos).

Ahora, en la práctica, su aplicación de libro de visitas probablemente esté haciendo una publicación AJAX de la nueva entrada de la publicación del libro de visitas. No es necesario volver a buscar todas las publicaciones después de enviar la nueva publicación. La aplicación web puede simplemente insertar la nueva entrada en la interfaz de usuario una vez que la solicitud AJAX haya tenido éxito. Para cuando el usuario abandone la página web y regrese a ella, o incluso presione el botón de actualización del navegador, habrán transcurrido varios segundos, y es muy probable que la nueva consulta regrese todas las publicaciones del libro de visitas.

Finalmente, tenga en cuenta que el rendimiento de coherencia eventual se aplica solo a las consultas . Si put() una entidad e inmediatamente llama a db.get() para recuperarla, el resultado es muy consistente, es decir, obtendrá la última instantánea de la entidad.


Configuración de ejemplo de blog obligatorio; Authors tienen Posts

class Author(db.Model): name = db.StringProperty() class Post(db.Model): author = db.ReferenceProperty() article = db.TextProperty() bob = Author(name=''bob'') bob.put()

Lo primero que debe recordar es que el get / put / delete regular en un solo grupo de entidades (incluida una única entidad) funcionará como se espera:

post1 = Post(article=''first article'', author=bob) post1.put() fetched_post = Post.get(post1.key()) # fetched_post is latest post1

Solo podrá notar la inconstancia si comienza a consultar en múltiples grupos de entidades. A menos que haya especificado un atributo parent , todas sus entidades están en grupos de entidades separadas. Entonces, si era importante que justo después de que bob creara una publicación, que él pudiera ver su propia publicación, entonces deberíamos tener cuidado con lo siguiente:

fetched_posts = Post.all().filter(''author ='', bob).fetch(x) # fetched_posts _might_ contain latest post1

fetched_posts puede contener la última post1 de bob , pero podría no ser así. Esto se debe a que todas las Posts no están en el mismo grupo de entidades. Al hacer una consulta como esta en HR, deberías pensar "tráeme probablemente las últimas publicaciones de bob" .

Dado que es importante en nuestra aplicación que el autor pueda ver su publicación en la lista inmediatamente después de crearla, usaremos el atributo parent para unirlas, y usaremos una consulta de ancestor para obtener las publicaciones solo desde ese grupo:

post2 = Post(parent=person, article=''second article'', author=bob) post2.put() bobs_posts = Post.all().ancestor(bob.key()).filter(''author ='', bob).fetch(x)

Ahora sabemos que post2 estará en nuestros resultados de bobs_posts .

Si el objetivo de nuestra consulta era obtener "probablemente todas las últimas publicaciones + definitivamente las últimas publicaciones de bob", tendríamos que hacer otra consulta.

other_posts = Post.all().fetch(x)

A continuación, other_posts los resultados other_posts y bobs_posts para obtener el resultado deseado.