2011-12-11 11 views
62

Me gustaría agregar capacidades de almacenamiento en caché a mi aplicación utilizando el espacio de nombres System.Runtime.Caching, y probablemente quiera usar el almacenamiento en caché en varios lugares y en diferentes contextos. Para hacerlo, quiero usar varias instancias de MemoryCache.Uso de varias instancias de MemoryCache

Sin embargo, veo here que el uso de más de una instancia de MemoryCache se desanima:

MemoryCache no es un producto único, pero debe crear sólo unos pocos o potencialmente sólo una instancia MemoryCache y el código que se almacena en caché los artículos debería usar esas instancias.

¿Cómo afectarían a mi aplicación las múltiples instancias de MemoryCache? Encuentro este tipo de cosas raras porque me parece que usar múltiples cachés en una aplicación es un escenario bastante común.

EDIT: Más específicamente, tengo una clase que debe mantener un caché para cada instancia. ¿Debería evitar usar MemoryCache y buscar una solución de almacenamiento en caché diferente? Está usando MemoryCache en esta situación considerada mala, y si es así, ¿por qué?

+1

¿Cuál es la diferencia entre un solo caché y muchos cachés? Después de todo, todos van a hacer lo mismo. – spender

+9

Por un lado, no tendré que preocuparme tanto por las colisiones clave. Además, creo que es más organizado y más fácil de depurar que tener un objeto que contenga todo lo que la aplicación almacena en caché. –

+5

Significa que no debe crear muchos cachés que almacenan en caché lo mismo. Es mucho mejor almacenar en caché todo lo que sea posible con un caché central. Pero está perfectamente bien crear muchos cachés que hacen caché de cosas diferentes. –

Respuesta

57

Recientemente, he pasado por esto yo también. Teniendo en cuenta que un caché en memoria será específico del proceso (no compartido en varias instancias de un sitio web o aplicación empresarial nativa o múltiples servidores), no hay ningún beneficio en tener múltiples MemoryCache instancias, excepto por razones organizativas del código (que se pueden lograr de otras maneras) .

El caché de memoria está destinado a ser utilizado solo principalmente debido a sus capacidades de gestión de memoria. Además de los contadores de rendimiento (que tienen cierta sobrecarga), MemoryCache también puede caducar los artículos cuando se queda sin memoria asignada.

Si la instancia actual de la caché excede el límite de memoria de ajuste directamente en el hotel CacheMemoryLimit, la implementación de caché elimina entradas de caché. Cada instancia de caché en la aplicación puede usar la cantidad de memoria especificada por la propiedad CacheMemoryLimit.

de MemoryCache.CacheMemoryLimit Property

Mediante el uso de sólo una instancia de la MemoryCache se puede aplicar esta gestión de memoria de manera eficiente a través de toda la instancia de aplicación. Expiración de los elementos menos importantes en toda la aplicación. Esto asegura el máximo uso de la memoria, sin exceder las capacidades de su hardware. Al limitar el alcance de una MemoryCache (como una instancia de una clase), ya no puede administrar la memoria de manera efectiva para su aplicación (ya que no puede "ver" todo). Si todos estos cachés estuvieran "ocupados" puede que le cueste más administrar la memoria y nunca será tan eficiente.

Esto es particularmente sensible en aplicaciones que no tienen el lujo de un servidor dedicado.Imagine que está ejecutando su aplicación en un servidor compartido donde solo le han asignado 150 mb de RAM (alojamiento común barato a $ 10 por mes) necesita contar con su caché para usarla al máximo sin excederlo. Si supera este uso de memoria, su grupo de aplicaciones se reciclará y su aplicación perderá todo en cachés de memoria. (Práctica común de alojamiento barato) Lo mismo podría aplicarse a una aplicación no web alojada en la casa en algún servidor corporativo compartido. El mismo trato, se te dice que no tengas que almacenar toda la memoria en esa máquina y coexistir pacíficamente con otras aplicaciones de la línea de negocios.

Ese límite de memoria, reciclaje de grupo de aplicaciones, perder cachés es un "talón de Aquiles" común para las aplicaciones web. Cuando las aplicaciones están más ocupadas, se reinician con mayor frecuencia debido a la exageración de las asignaciones de memoria, la pérdida de todas las entradas de caché y, por lo tanto, hacer la mayor parte del trabajo de recuperación de cosas que deberían haberse almacenado en el caché en primer lugar. Lo que significa que la aplicación realmente pierde rendimiento a la carga máxima en lugar de ganar.

Sé que MemoryCache es la versión no específica de la web de la implementación System.Web.Caching.Cache, pero esto ilustra la lógica detrás de la implementación de la memoria caché. La misma lógica puede aplicarse en un proyecto que no sea web si no tiene un uso exclusivo del hardware. Recuerde que si su caché fuerza a la máquina a comenzar a hacer intercambios de archivos de paginación, entonces su caché ya no es más rápida que el almacenamiento en caché del disco. Siempre querrás un límite en alguna parte, incluso si ese límite es de 2 GB o algo así.

En mi caso, después de leer acerca de esto, cambié a usar una 'MemoryCache estática pública' en mi aplicación y simplemente segregé los elementos en caché por sus claves de caché. Por ejemplo, si desea almacenar en caché una instancia por instancia, podría tener una clave de caché como algo como "instancia- {ID de instancia} -nombre de recurso- {ID de recurso}". Piense en ello como el espaciado entre sus entradas de caché.

Espero que ayude!

+2

Gracias, eso fue servicial. Sin embargo, no estoy tratando de limitar mi caché en función del tamaño de la memoria, pero posiblemente por la capacidad, donde quiero que cada instancia tenga cierta capacidad y no me importan las cachés combinadas. Segregar elementos de caché mediante una convención de nomenclatura no es bueno para ese caso, y parece un poco forzado de cualquier manera. –

+1

@AdiLester Lo tienes perfecto. Idealmente, Microsoft terminaría de implementar las "Regiones" de caché para su 'Caché de memoria ', de modo que no necesitaría estas claves forzadas de" espacio de nombres "y podría consultar el número de elementos en caché en cualquier Región. Pero eso no es compatible actualmente con la implementación de la caché que no es web. :-(Mientras tanto, parece que conoce sus limitaciones y está de acuerdo con ellas. – BenSwayne

+0

Puede mostrar algún ejemplo de código que explique el beneficio del uso anterior sobre Single Instance. En este se volverá más útil y más popular. –

4

Yo uso varios también. Generalmente uno por tipo.

Al mirar el MemoryCache veo que se engancha en los eventos AppDomain y mantiene los contadores de rendimiento. Sospecho que hay un poco de recursos generales por el uso de más de uno (por ejemplo, CPU, contadores y memoria) y es por eso que se desaconseja.

Cuestiones relacionadas