2010-06-03 8 views
21

La base de datos moderna proporciona soporte de caché. La mayoría de los marcos ORM también almacenan en caché los datos recuperados. ¿Por qué esta duplicación es necesaria?¿Por qué utilizar su caché de nivel de aplicación si la base de datos ya proporciona almacenamiento en caché?

+0

Algunos enlaces relevantes: http://docs.jboss.org/hibernate/stable/core/reference/en/html/performance.html#performance-cache y también: http: // www .javalobby.org/java/forums/t48846.html –

Respuesta

35

debido a obtener los datos de la memoria caché de la base de datos, usted todavía tiene que:

  1. Generar el SQL de formato de consulta "nativa" de la ORM
  2. hacer una red de ida y vuelta al servidor de base de datos
  3. Analizar el SQL
  4. Recuperar los datos de la caché
  5. serializar los datos a el formato de la base de datos
  6. Deserializar los datos en el formato de la biblioteca cliente de la base de datos
  7. Convierta el formato de la biblioteca del cliente de la base de datos en objetos de nivel de idioma (es decir, una colección de elementos)

Al almacenar en caché a nivel de aplicación, no tiene que hacer nada de eso. Por lo general, es una búsqueda simple de una tabla hash en memoria. A veces (si se almacena en caché con Memcache) todavía hay una red de ida y vuelta, pero todas las otras cosas ya no ocurren.

+0

Sin mencionar enlaces de red lentos, etc. –

9

Aquí hay un par de razones por las que puede querer esto:

  • caché una aplicación justo lo que necesita por lo que debe tener una mejor memoria caché proporción de aciertos
  • Acceso a una caché local será probablemente un par de órdenes de magnitud más rápido que el acceso a la base de datos debido a la latencia de la red - incluso con una red rápida
6

Incluso si un motor de base de datos almacena en la memoria caché los datos, los índices o los conjuntos de resultados de las consultas, aún se necesita un viaje de ida y vuelta a la base de datos para que su aplicación se beneficie de esa caché.

Una estructura ORM se ejecuta en el mismo espacio que su aplicación. Entonces no hay ida y vuelta. Es solo un acceso de memoria, que generalmente es mucho más rápido.

El marco también puede decidir mantener los datos en caché todo el tiempo que lo necesite. La base de datos puede decidir caducar los datos almacenados en caché en momentos impredecibles, cuando otros clientes simultáneos realizan solicitudes que utilizan el caché.

Su marco ORM del lado de la aplicación también puede almacenar en caché los datos de una forma que la base de datos no puede devolver. P.ej. en forma de una colección de objetos Java en lugar de una secuencia de datos sin formato. Si confía en el almacenamiento en caché de la base de datos, su ORM tiene que repetir esa transformación en objetos, lo que se suma a la sobrecarga y disminuye el beneficio de la memoria caché.

4

Además, la memoria caché de la base de datos puede no ser tan práctica como se cree. Copié esto de http://highscalability.com/bunch-great-strategies-using-memcached-and-mysql-better-together - es específico de MySQL, aunque.

Dado que MySQL tiene un caché, ¿por qué se necesita memcached en absoluto?

La memoria caché de MySQL está asociada a una sola instancia. Esto limita la memoria caché a la dirección máxima de un servidor. Si su sistema es más grande que la memoria para un servidor, el uso de la memoria caché MySQL no funcionará. Y si el mismo objeto se lee desde otra instancia, no está en la memoria caché.

La caché de consultas invalida las escrituras. Construyes todo ese caché y desaparece cuando alguien escribe en él. Es posible que su caché no sea una gran cantidad de caché según los patrones de uso.

El caché de consultas está basado en filas. Memcached puede almacenar en caché cualquier tipo de datos que desee y no está limitado a las filas de la base de datos de caché. Memcached puede almacenar en caché objetos complejos complejos que son directamente utilizables sin una unión.

4

Se han señalado correctamente las consideraciones de rendimiento relacionadas con los viajes de ida y vuelta de la red.

Para eso, se debe agregar que los datos de almacenamiento en caché en cualquier lugar que no sea en el dbms (NO "base de datos"), crea un problema de datos potencialmente obsoletos que todavía se presentan como "actualizados".

Ceder a las tentaciones de la mejora del rendimiento va a expensas de perder la garantía (estanca o al menos cercana) de datos absolutamente fiables y garantizados correctos y coherentes.

Considere esto cada vez que la precisión y la consistencia son cruciales.

3

No hay duda de que las bases de datos modernas proporcionan almacenamiento en caché pero cuando tiene más tráfico en su sitio y esa vez necesita realizar muchas transacciones de base de datos, entonces no obtendrá alto rendimiento. Para aumentar el rendimiento en este caso hibernate caché lo ayudará, mediante la optimización de las aplicaciones de base de datos. El caché realmente almacena los datos ya cargados de la base de datos, de modo que el tráfico entre nuestra aplicación y la base de datos se reducirá cuando la aplicación quiera acceder a esos datos nuevamente. El tiempo de acceso y el tráfico se reducirán entre la aplicación y la base de datos.

4

Muchas buenas respuestas aquí. Añadiré otro punto: I conozco mi patrón de acceso, la base de datos no.

Dependiendo de lo que estoy haciendo, sé que si los datos terminan obsoletos, eso no es realmente un problema. El DB no lo hace y debería volver a cargar el caché con los datos nuevos.

Sé que volveré a un dato varias veces durante el próximo tiempo, por lo que es importante estar cerca. El DB tiene que adivinar qué guardar en el caché, no tiene la información que yo tengo. Entonces, si lo recojo de la base de datos una y otra vez, puede que no esté en la memoria caché si el servidor está ocupado. Podría obtener un error de caché. Con mi caché, puedo estar seguro de recibir un golpe. Esto es especialmente cierto en datos que no son triviales (es decir, algunas combinaciones, algunas funciones de grupo) en oposición a una sola fila. Obtener una fila con la clave primaria de 7 es fácil para el DB, pero si tiene que hacer un trabajo real, el costo de la falta de caché es mucho mayor.

2

Dicho esto: las memorias caché a veces pueden convertirse en una carga y realmente ralentizar el servidor. Cuando tienes carga alta, el algoritmo de lo que se almacena en caché y lo que no puede no coincidir con las solicitudes entrantes ... lo que obtienes es un caché que comienza a operar como FIFO en tiempo extra ... esto comienza a darse a conocer cuando la tabla que se encuentra detrás de la memoria caché tiene muchos más registros que los que se almacenarán en la memoria ...

Una buena solución sería agrupar los datos de lo que desea almacenar en caché. Tener un servidor principal que bombea actualizaciones a los clusters, el tiempo para cuándo enviar/bombear las actualizaciones debe ser adaptado para cada tabla dependiendo de la configuración TTL (tiempo de vida).

Su lógica y datos en el nodo de usuario pueden sentarse en el mismo servidor que se abre en las bases de datos de memoria o si tiene que buscar datos, entonces puede configurarlos para usar un conducto en lugar de una llamada de red.

Esto es algo que toma alguna reflexión sobre cómo desea utilizar los datos y cuándo/si se agrupa entonces tiene que ser consciente de las transacciones distribuidas (transacciones en más de una base de datos) ... pero si los datos ser almacenado en caché se actualizará por sí mismo sin enlaces a otros espacios db, entonces puede salirse con la suya ....

El problema con el almacenamiento en caché de ORM es que si la base de datos se actualiza de forma independiente a través de otra aplicación entonces la memoria caché de ORM puede volverse obsoleta ... También puede ser complicado si hace una actualización de un conjunto ... la actualización podría actualizar algo que está en su caché y necesita tener algún tipo de algoritmo para identificar qué los registros deben ser eliminados/actualizados en la memoria (ralentizando la actualización !?) - y luego este algoritmo se vuelve increíblemente complicado y propenso a errores.

Si utiliza el almacenamiento en caché de ORM, siga una regla simple ... caché de objetos simples que casi nunca cambian (detalles de usuario/función por ejemplo) y que son pequeños y se golpean muchas veces en una solicitud ... si está fuera de esto, entonces sugiero agrupar los datos para el rendimiento.

Cuestiones relacionadas