2010-09-29 18 views
5

Actualmente estoy desarrollando la base de una aplicación y estoy buscando formas de optimizar el rendimiento. Mi configuración se basa en the CakePHP framework, pero creo que mi pregunta es relevante para cualquier pila de tecnología, ya que se relaciona con el almacenamiento en memoria caché de datos.Patrones para el almacenamiento en caché de datos relacionados

Tomemos una relación típica post-autor, que está representada por 2 tablas en mi db. Cuando consulto la base de datos para una publicación de blog específica, al mismo tiempo la funcionalidad ORM incorporada en CakePHP también busca al autor de la publicación, comentarios en la publicación, etc. Todo esto se devuelve como una matriz anidada de gran culo , que almaceno en caché usando un identificador único para la publicación de blog correspondiente.

Al actualizar la publicación del blog, es un juego de niños destruir la memoria caché de la publicación y volver a generarla con la siguiente solicitud.

Pero, ¿qué pasa cuando no se actualiza la entidad principal (en este caso, la publicación del blog), sino más bien algunos de los datos relacionados? Por ejemplo, un comentario podría eliminarse, o el autor podría actualizar su avatar. ¿Hay algún enfoque (patrones) que pueda considerar para rastrear actualizaciones de datos relacionados y aplicar actualizaciones a mi caché en consecuencia?

Tengo curiosidad por saber si también ha enfrentado desafíos similares y cómo ha logrado superar el obstáculo. Siéntase libre de proporcionar una perspectiva abstracta, si está utilizando otra pila en su extremo. Sus opiniones son de todos modos muy apreciadas, ¡muchas gracias!

Respuesta

2

Es bastante simple, entradas de caché pueden ser

  • añade
  • destruidos

Usted debe tener cuidado de destruir las entradas de caché cuando se relaciona el cambio de datos (lo que en la capa de aplicación, además de al actualizar los datos, debe destruir ciertos tipos de entradas almacenadas en caché cuando actualiza ciertas tablas; realiza un seguimiento de las dependencias codificándolas por hardware).

Si desea ser inteligente al respecto, podría hacer que su objeto de caché establezca sus dependencias y almacenar en caché los últimos tiempos de actualización para sus tablas de bases de datos también.

entonces se podría

  • obtener los datos almacenados en caché, examinar las dependencias,
  • tiempos de actualización get para las tablas pertinentes DB y
  • en caso de que el registro está demasiado cargado (tiempo de actualización de una tabla que su gran culo la entrada de caché depende de es posterior a la hora de la entrada de caché) soltarlo y obtener datos actualizados de la base de datos.

Incluso puede integrar lo anterior en su capa de persistencia.

EDIT:
Por supuesto, lo anterior es para cuando se desea tener caché coherente. A veces, y para algunos datos, puede relajar los requisitos de coherencia y hay escenarios donde el TTL simple será lo suficientemente bueno (para un ejemplo trivial, si tiene un ttl de 1 segundo, en su mayoría debería estar fuera de problemas con los usuarios y puede ayudar procesamiento de datos, y con tiempos más altos puede que todavía esté bien, por ejemplo, digamos que está almacenando en caché la lista de códigos ISO del país; su aplicación podría estar perfectamente bien si usted dice caché esto durante 86400 segundos).

Por otra parte, también se puede realizar un seguimiento de los tiempos de la información presentada al usuario, por ejemplo

  • digamos usuario ha visto los datos Una de caché y que sabemos que estos datos fue creada/modificada en el tiempo t1
  • el usuario realiza cambios en los datos A (y los convierte en datos B) y confirma el cambio
  • la capa de aplicación puede examinar si los datos A aún están en DB (si los datos en caché en los que el usuario tomó decisiones y/o los cambios fueron realmente recientes)
  • si fue no fresco, entonces hay un conflicto y el usuario debe confirmar los cambios

Esto tiene un coste de lectura adicional de los datos de una base de datos, sino que se produce sólo en las escrituras. Además, el conflicto puede ocurrir no solo debido a la memoria caché, sino también debido a que varios usuarios intentan cambiar los datos (es decir, está relacionado con estrategias de bloqueo).

+0

Tenía miedo de que esto fuera la única salida posible, pero gracias por confirmar que, ya que lograron que suene más "capaz" :-) Así que la desventaja es una gran cantidad de código personalizado por vista, pero Lo bueno es que esto aún permitiría una fácil conmutación del back-end de caché. Thx también para obtener información adicional sobre la función de bloqueo, esta será para v2 :-) – Shahways

+0

Para una visión conceptual más compleja y algunos temas prácticos, encontré esta lectura interesante http://highscalability.com/blog/2010/9/ 30/facebook-and-site-failures-caused-by-complex-weakly-interact.html – Unreason

1

One Approach para memcached es usar etiquetas (http://code.google.com/p/memcached-tag/). Por ejemplo, tiene su "matriz anidada de gran culo" de Post, digamos que incluye la información de autors, la publicación misma y se muestra en la página principal y en algún recuadro en la barra lateral. Por lo tanto, recibe las etiquetas: página principal, {auhothor-id}, barra lateral, {post-id}: ahora, si alguien cambia la información del autor, vacía cada entrada de la memoria caché con la etiqueta {author-id}. Pero esa es solo una Solución, y solo para los Backends de caché que soportan Tags, por ejemplo, no APC (afaik). Espero que te haya dado un ejemplo.

+0

Hannes, thx para señalar esto. He investigado en memcached, pero no me di cuenta de que esta opción existía. – Shahways

Cuestiones relacionadas