使用多个 MemoryCache 实例 [英] Using multiple instances of MemoryCache

查看:25
本文介绍了使用多个 MemoryCache 实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 System.Runtime.Caching 命名空间向我的应用程序添加缓存功能,并且可能希望在多个位置和不同上下文中使用缓存.为此,我想使用多个 MemoryCache 实例.

I'd like to add caching capabilities to my application using the System.Runtime.Caching namespace, and would probably want to use caching in several places and in different contexts. To do so, I want to use several MemoryCache instances.

但是,我看到这里不鼓励使用多个 MemoryCache 实例:

However, I see here that using more than one instance of MemoryCache is discouraged:

MemoryCache 不是单例,但您应该只创建几个或可能只创建一个 MemoryCache 实例,并且缓存项目的代码应该使用这些实例.

MemoryCache is not a singleton, but you should create only a few or potentially only one MemoryCache instance and code that caches items should use those instances.

多个 MemoryCache 实例将如何影响我的应用程序?我觉得这很奇怪,因为在我看来,在一个应用程序中使用多个缓存是很常见的情况.

How would multiple MemoryCache instances affect my application? I find this kind of weird because it seems to me that using multiple caches in an application is a pretty common scenario.

更具体地说,我有一个类应该为每个实例保留一个缓存.我应该避免使用 MemoryCache 并寻找不同的缓存解决方案吗?在这种情况下使用 MemoryCache 是否被认为是不好的,如果是,为什么?

More specifically, I have a class that should keep a cache for each instance. Should I avoid using MemoryCache and look for a different caching solution? Is using MemoryCache in this situation considered bad, and if so, why?

推荐答案

我最近自己也经历了这个.考虑到内存缓存将是特定于进程的(不会在网站或本机业务应用程序的多个实例或多个服务器之间共享),除了代码组织原因之外,拥有多个 MemoryCache 实例实际上没有任何好处(可以通过其他方式实现).

I recently went through this myself as well. Considering an in memory cache will be process specific (not shared across multiple instances of a website or native business app or multiple servers) there is really no benefit to having multiple MemoryCache instances except for code organizational reasons (which can be achieved in other ways).

内存缓存主要是因为其内存管理功能而旨在单独使用.除了性能计数器(确实有一些开销)之外,MemoryCache 还能够在分配的内存用完时使项目过期.

The Memory cache is intended to be used alone mostly because of its memory management capabilities. In addition to the performance counters (which do have some overhead) the MemoryCache is also able to expire items when it runs out of allocated memory.

如果缓存的当前实例超过了设置的内存限制通过 CacheMemoryLimit 属性,缓存实现删除缓存条目.应用程序中的每个缓存实例都可以使用CacheMemoryLimit 属性指定的内存量.

If the current instance of the cache exceeds the limit on memory set by the CacheMemoryLimit property, the cache implementation removes cache entries. Each cache instance in the application can use the amount of memory that is specified by the CacheMemoryLimit property.

来自 MemoryCache.CacheMemoryLimit 属性

通过只使用 MemoryCache 的一个实例,它可以在整个应用程序实例中有效地应用这种内存管理.使整个应用程序中最不重要的项目过期.这可确保最大程度地使用内存,而不会超出您的硬件能力.通过限制任何一个 MemoryCache 的范围(比如一个类的一个实例),它不能再有效地管理应用程序的内存(因为它不能看到"一切).如果所有这些缓存都繁忙",您可能会更难管理内存,而且效率永远不会那么高.

By using only one instance of the MemoryCache it can apply this memory management efficiently across the entire application instance. Expiring the least important items across the entire application. This ensures maximum memory use, without exceeding your hardware capabilities. By limiting the scope of any one MemoryCache (like to one instance of a class) it can no longer effectively manage memory for your application (as it can't "see" everything). If all of these cache's were "busy" you may have a harder time managing memory and it will never be nearly as efficient.

这在没有专用服务器的应用程序中尤为敏感.想象一下,您在共享服务器上运行您的应用程序,您只分配了 150 mb RAM(通常为每月 10 美元的廉价托管),您需要依靠缓存来最大程度地使用它而不会超过它.如果超过此内存使用量,您的应用程序池将被回收,并且您的应用程序将丢失所有内存缓存!(常见的廉价托管实践)同样适用于内部托管在某些共享公司服务器上的非 Web 应用程序.同样的交易,你被告知不要占用那台机器上的所有内存,而要与其他一些业务应用和平共处.

This is particularly sensitive in applications which don't have the luxury of a dedicated server. Imagine you are running your app on a shared server where you've only been allocated 150mb RAM (common cheap $10/month hosting) you need to count on your cache to use that to the max without exceeding it. If you exceed this memory usage your app pool will be recycled and your app loses all in memory caches! (common cheap hosting practice) The same could apply to a non-web app hosted in house on some shared corporate server. Same deal, you're told not to hog all the memory on that machine and to peacefully co-exist with some other line of business apps.

内存限制、应用程序池回收、丢失缓存是网络应用程序常见的致命弱点".当应用程序最忙时,由于超出内存分配,它们会最频繁地重置,丢失所有缓存条目,因此做最多的工作来重新获取应该首先缓存的内容.这意味着应用程序实际上会在最大负载下失去性能而不是获得性能.

That memory-limit, app pool recycle, lose caches thing is a common "Achilles heel" to web apps. When the apps are their busiest, they reset the most often due to exceeding memory allocations, losing all cache entries and therefor doing the most work re-fetching stuff that should have been cached in the first place. Meaning the app actually loses performance at max load instead of gaining.

我知道 MemoryCache 是 System.Web.Caching.Cache 实现的非 Web 特定版本,但这说明了缓存实现背后的逻辑.如果您没有独占使用硬件,则相同的逻辑可以应用于非 Web 项目.请记住,如果您的缓存强制机器开始进行页面文件交换,那么您的缓存不再比在磁盘上缓存快.您总是希望在某处设置限制,即使该限制是 2GB 之类的.

I know MemoryCache is the non-web specific version of System.Web.Caching.Cache implementation, but this illustrates the logic behind cache implementation. The same logic can apply in a non-web project if you don't have exclusive use of the hardware. Remember if your cache forces the machine to start doing pagefile swaps then your cache is no longer any faster than caching on disk. You'll always want a limit somewhere, even if that limit is 2gb or something.

就我而言,在阅读完相关内容后,我切换到在我的应用程序中使用一个公共静态 MemoryCache",并且我只是通过它们的缓存键来隔离缓存的项目.例如,如果你想在每个实例上缓存,你可以有一个像instance-{instanceId}-resourceName-{resourceId}"这样的缓存键.把它想象成你的缓存条目的名称间隔.

In my case after reading up about this, I switched to using one 'public static MemoryCache' in my app and I simply segregated cached items by their cache keys. For example if you want to cache on a per instance you could have a cache key like something like "instance-{instanceId}-resourceName-{resourceId}". Think of it as name spacing your cache entries.

希望有帮助!

这篇关于使用多个 MemoryCache 实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆