net 4 中的 MemoryCache是 有什么作用?这缓存能不能常驻内存

我在已更改MemoryCache是类以使其可用 不是ASP.NET應用程序的框架应用程序 例如, MemoryCache是类与System.Web程序集无关 另一个区别是您可以创建 在同一应用程序和同一应用程序中使用的MemoryCache是类 AppDomain实例。

阅读並在反射代码中进行一些研究很明显RemoveCallback只是一个简单的类。 您可以使用MemoryCache是.Default属性来(重新)使用同一实例也可以根据需要构造任意数量的實例(尽管建议的数量尽可能少)。

因此基本上答案就在您的代码中。
如果使用RemoveCallback则只要应用程序池存在,高速缓存就会保留 (仅提醒您,默认的应用程序池空闲超时为20分钟不到1小时。)

如果使用RemoveCallback创建实例那么上述注意事项将适用于您在其中创建实例的上下文,也僦是说如果您在控制器内部创建实例(我希望情况并非如此),则您的缓存可以保留一个请求

很遗憾我找不到任何引用,但是... RemoveCallback不保证根据您指定的缓存策略保存数据 特别是,如果您正在运行应用程序的计算机在内存上压力很大则您的缓存可能会被丢弃。

如果仍然没囿运气找出早期缓存项失效的原因是什么则可以利用RemoveCallback并调查项失效的原因是什么。

一年后进行回顾我在原始帖子中发现了有关缓存随機“丢弃”的更多信息。 MSDN针对可配置的缓存属性MemoryCache是Cache是MemoryLimitMegabytes声明以下内容:

默认值为0这表示MemoryCache是类的 默认情况下使用自动调整启发式。

通过进荇一些反编译和研究在MemoryCache是类中预先定义了一些场景,这些场景定义了内存阈值 这是该类中Cache是MemoryLimitMegabytes属性的注释样本:

特定的值不一定与实现為什么经常使用缓存一样重要:存储我们不想一遍又一遍地获取的大对象。 如果将这些大对象存储在缓存中并且超出了基于这些内部计算的主机环境内存阈值,则可能会自动从缓存中删除该项目 这肯定可以解释我的OP,因为我在托管服务器上的内存中存储了一个非常大的集合其中可能有2GB的内存在IIS中运行多个应用程序。

除非注明文章均为 原创,欢迎轉载!转载请注明本文地址,谢谢

之前写过一篇关于JVM内存参数设置的文章(/jvm_xmx_xmn_xms_shezhi.html),设置方式本身没有很大问题但却忽略了一个点,如果站點中使用了缓存的话 这种设置方式可能会导致堆内存不够用。 一方面是因为缓存基本上不能被回收掉另一方面,缓存可能并不是立马僦能到达容量上限所以当系统运行比较长一段时间之后再设置内存,相对会得到一个比较合适的大小 

但系统运行相对较长一段时间在莋内存的大小分配,时间周期会比较长操作起来时间周期太长,不利于线上操作 

最近我们遇到了一个线上的Case

年前我们做压测的时候,將某站点部署到沙箱机中进行测试使用jmap 等方式强制GC后,按照之前的经验设置了4G堆内存,其中新生代2G,年老代2G沙箱机压测时YGC和FGC正常,未出现频繁GC的情况于是,我们将这个内存设置同步到线上了

但系统运行一段时间之后,发现系统出现了频繁的FGCjstat查看GC情况如下:

从仩图中可以看出, 基本8s就产生了一次FGC且FGC之后老年代的内存使用率并未降下来,始终维持在95%左右 

PS:正常线上是不可以直接打内存快照的,因为会导致stw建议先摘掉机器之后,再打内存快照防止影响线上服务。

原本想用jhat来提供一个线上访问的入口但发现服务器在执行jhat的時候耗时太久了,于是将内存快照保存到了本地用本地的MAT来做了一下查看。

查看代码发现系统使用ehchache作为缓存,我们线上还有16G的站点查看线上的情况,基本上老年代维持在1.96-2.38G左右 

所以问题也就基本明了了, 因为老年代的内存为2G但缓存又占用的比较大,占用到了1.9G以上所以就会触发FGC,但缓存中的数据又不能被GC清除掉所以GC之后,老年代的占比依旧没怎么变化之后就反反复复的触发FGC了。 

知道问题了解決办法相对也就简单了。 调整jvm的参数加大堆内存可以解决。

加大堆内存虽然可以解决但是依旧可能存在问题

    比如,如果缓存的值大小變大虽然个数不变,那么也会导致整体所占用内存变大这样原本设置的堆内存大小可能还会再次出现不够的情况

    缓存数据一般会常驻內存中一段时间,GC无法保证回收时会被回收掉所以可能导致GC的无用功及GC的频率/时长变多。

有种办法是将本地缓存使用分布式缓存代替泹这样虽然能使本地内存变少,但却带来了额外的网络开销 

另外一种办法是利用堆外内存来解决,将缓存缓存到堆外不影响到GC,因为堆外内存增长不涉及到堆参数即使缓存数据增长的时候,也不会影响到正常的业务逻辑 

PS:在使用对外内存的时候,不要忘记添加JVM参数:-XX:MaxDirectMemorySize  来限制下堆外内存的大小同时,这个-XX:+DisableExplicitGC 参数需要注意 这个参数设定了之后将禁止显式调用GC,但这个可能会影响到堆外内存的回收


长按下方二维码关注我~

MemCache是d采用客户端-服务器的架构客戶端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求客户端Library可以用任何语言实现。

MemCache是d服务器使用基于Slab的内存管理方式有利于减少内存碎片和频繁分配销毁内存所带来的开销。各个Slab按需动态分配一个page的内存(和4Kpage的概念不同这里默认page1M),page内部按照不同slab class嘚尺寸再划分为内存chunk供服务器存

KV键值对使用(slab机制相当于内存池机制, 实现从操作系统分配一大块内存, 然后 memCache是d 自己管理这块内存, 负责分配與回收)

1、关于memCache是d的内存分配机制:

      实际MySQL是适合进行海量数据存储的,通过MemCache是d将热点数据加载到Cache是加速访问,很多公司都曾经使用过這样的架构但随着业务数据量的不断增加,和访问量的持续增长我们遇到了很多问题:

IF id_等。作为媒体公司这些网站上的文档、图片、视频短片都在无时无刻的更新。长话短说下面就进入Viacom高级架构师Michael Venezia 分享的Redis实践:

Viacom的网站架构背景

对于Viacom,横跨多个站点传播内容让必须专紸于规模的需求同时为了将内容竟可能快的传播到相应用户,他们还必须聚焦内容之间的关系然而即使The Daily Show、Nickelodeon、Spike或者是VH1 这些单独的网站上,日平均PV都可以达到千万峰值时流量更会达到平均值的20-30倍。同时基于对实时的需求动态的规模及速度已成为架构的基础之一。

除去动態规模之外服务还必须基于用户正在浏览的视频或者是地理位置来推测用户的喜好。比如说某个页面可能会将一个独立的视频片段与夲地的促销,视频系列的额外部分甚至是相关视频联系起来。为了能让用户能在网站上停留更长的时间他们建立了一个能基于详细元數据自动建立页面的软件引擎,这个引擎可以根据用户当下兴趣推荐额外的内容鉴于用于兴趣的随时改变,数据的类型非常广泛——类姒graph-like实际上做的是大量的join。

这样做有利于减少类似视频的大体积文件副本数比如数据存储中一个独立的记录是Southpark片段“Cartman gets an Anal Probe”,这个片段可能吔会出现在德语的网站上虽然视频是一样的,但是英语用户搜索的可能就是另一个不同的词语元数据的副本转换成搜索结果,并指向楿同的视频因此在美国用户搜索真实标题的情况下,德国浏览者可能会使用转译的标题——德国网站上的“Cartman und die Analsonde”

这些元数据覆盖了其它記录或者是对象,同时还可以根据使用环境来改变内容通过不同的规则集来限制不同地理位置或者是设备请求的内容。

尽管许多机构通過使用ORM及传统关系型数据库来解决这个问题Viacom却使用了一个迥然不同的方法。

本质上他们完全承担不了对数据库的直接访问。首先他們处理的大部分都是流数据,他们偏向于使用Akamai从地理上来分配内容其次,基于页面的复杂性可能会取上万个对象取如此多的数据显然會影响到性能,因此JSON在1个数据服务中投入了使用当然,这些JSON对象的缓存将直接影响到网站性能同时,当内容或者是内容之间的关系发苼改变时缓存还需要动态的进行更新。

Viacom依靠对象基元和超类解决这个问题继续以South Park为例:一个私有的“episode”类包含了所有该片段相关信息,一个“super object”将有助于发现实际的视频对象超类这个思想确实非常有益于建设低延迟页面的自动建设,这些超类可以帮助到基元对象到缓存的映射及保存

每当Viacom上传一个视频片段,系统将建立一个私有的对象并于1个超类关联。每一次修改他们都需要重估私有对象的每个妀变,并更新所有复合对象同时,系统还需要无效Akamail中的URL请求系统现有架构的组合及更敏捷的管理方法需求将Viacom推向了Redis。

基于Viacom主要基于PHP所以这个解决方案必须支持PHP。他们首先选择了memCache是d做对象存储但是它并不能很好的支持hashmap;同时他们还需要一个更有效的进行无效步骤的重估,即更好的理解内容的依赖性本质上说,他们需要时刻跟进无效步骤中的依赖性改变因此他们选择了Redis及Predis的组合来解决这个问题。

他們团队使用Redis给两个网站建设依赖性图在取得了很大的成功后他们开始着眼Redis其它适合场景。

Redis的其它使用场景

显而易见如果有人使用Redis来建設依赖性图,那么使用它来做对象处理也是说得通的同样,这也成了架构团队为Redis选择的第二使用场景Redis的复制及持久化特性同时也征服叻Viacom的运营团队,因此在几个开发周期后Redis成为他们网站的主要数据及依赖性储存。

后两个用例则是行为追踪及浏览计数的缓冲改变后的架构是Redis每几分钟向MySQL中储存一次,而浏览计数则通过Redis进行存储及计数同时Redis还被用来做人气的计算,一个基于访问数及访问时间的得分系统——如果某个视频最近被访问的次数越多它的人气就越高。在如此多内容上每隔10-15分钟做一次计算绝对不是类似MySQL这样传统关系型数据库的強项Viacom使用Redis的理由也非常简单——在1个存储浏览信息的Redis实例上运行Lua批处理作业,计算出所有的得分表信息被拷贝到另一个Redis实例上,用以支持相关的产品查询同时还在MySQL上做了另一个备份,用以以后的分析这种组合会将这个过程耗费的时间降低60倍。

Viacom还使用Redis存储一步作业信息这些信息被插入一个列表中,工作人员则使用命令行在队列中抓取顶端的任务同时zsets被用于从众多社交网络(比如Twitter及Tumblr)上综合内容,Viacom通过Brightcove视频播放器来同步多个内容管理系统

我要回帖

更多关于 nat的作用 的文章

 

随机推荐