Uso de varias instancias de MemoryCache


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

Sin embargo, veo aquí que se desaconseja usar más de una instancia de MemoryCache:

MemoryCache no es un singleton, pero debe crear solo unas pocas o potencialmente solo una instancia de MemoryCache y el código que almacena en caché los elementos debe utilice esas instancias.

¿Cómo afectarían múltiples instancias de MemoryCache a mi aplicación? Me parece un poco raro porque me parece que el uso de múltiples cachés en una aplicación es un escenario bastante común.

EDIT: Más específicamente, tengo una clase que debería mantener una caché para cada instancia. ¿Debo evitar usar MemoryCache y buscar una solución de almacenamiento en caché diferente? Se considera malo usar MemoryCache en esta situación, y si es así, ¿por qué?

Author: Adi Lester, 2011-12-11

2 answers

Recientemente pasé por esto yo también. Teniendo en cuenta que una caché en memoria será específica del proceso (no compartida entre varias instancias de un sitio web o aplicación empresarial nativa o varios servidores), realmente no hay ningún beneficio en tener varias instancias MemoryCache, excepto por razones de organización del código (que se pueden lograr de otras maneras).

La caché de memoria está destinada a ser utilizada sola principalmente debido a sus capacidades de gestión de memoria. Además de los contadores de rendimiento (que tienen algo de sobrecarga) el MemoryCache también es capaz de caducar elementos cuando se queda sin memoria asignada.

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

De Memoria.CacheMemoryLimit Property

Por usando solo una instancia del MemoryCache puede aplicar esta administración de memoria de manera eficiente en toda la instancia de la aplicación. Expirando los elementos menos importantes en toda la aplicación. Esto garantiza el máximo uso de memoria, sin exceder las capacidades de hardware. Al limitar el alcance de cualquier 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 estaban "ocupados", es posible que tiene más dificultades para 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 se le han asignado 150 mb de RAM (alojamiento común barato de 1 10/mes), necesita contar con su caché para usarlo 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 casa en algún servidor corporativo compartido. El mismo trato, se te dice que no acapares toda la memoria en esa máquina y que coexistas pacíficamente con alguna otra línea de aplicaciones comerciales.

Ese límite de memoria, el reciclaje del grupo de aplicaciones, la pérdida de cachés es un "talón de Aquiles" común para las aplicaciones web. Cuando las aplicaciones están más ocupadas, se restablecen más a menudo debido a que exceden las asignaciones de memoria, perdiendo todas las entradas de caché y, por lo tanto, haciendo la mayor parte del trabajo de volver a buscar cosas que deberían haber sido almacenadas en caché en primer lugar. Lo que significa que la aplicación realmente pierde rendimiento con carga máxima en lugar de ganar.

Sé que MemoryCache es la versión no específica para web de System.Web.Cache.Implementación de caché, pero esto ilustra la lógica detrás de la implementación de caché. La misma lógica se puede aplicar en un proyecto no web si no tiene uso exclusivo del hardware. Recuerde si su caché obliga a la máquina a comenzar a realizar intercambios de archivos de página, entonces su caché ya no es más rápido que el almacenamiento en caché en disco. Siempre querrás un límite en algún lugar, incluso si ese límite es de 2 gb o algo así.

En mi caso después de leer sobre esto, cambié a usar un 'public static MemoryCache' en mi aplicación y simplemente segregé los elementos almacenados en caché por sus claves de caché. Por ejemplo, si desea almacenar en caché una instancia por, podría tener una clave de caché como algo como " instance - {InstanceID} - resourceName - {resourceId}". Piense en ello como el espaciado de nombres de su caché entrada.

Espero que ayude!

 62
Author: BenSwayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-05 15:09:57

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

Mirando el MemoryCache veo que se engancha en los eventos AppDomain y mantiene los contadores de rendimiento. Sospecho que hay algunos recursos de sobrecarga en cuanto al uso de más de uno (por ejemplo, CPU, contadores y memoria) y es por eso que se desaconseja.

 5
Author: Kit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-24 15:20:28