拥抱.NET Core系列:MemoryCache 缓存选项

在上一篇 ”拥抱.NET Core系列:MemoryCache 缓存过时” 中咱们详细的了解了缓存过时相关的内容,今天咱们来介绍一下 MSCache 中的 Options,由此来介绍一些 MSCache 中的内部机制。html

MSCache项目

MSCache 目前最新的正式版是 2.0.0,预览版是2.1.0,会与 .NETCore 2.1 一块儿发布。本篇用了2.0.0版本git

开源在 GitHub 上,仓库地址是:https://github.com/aspnet/Cachinggithub

NuGet地址为:https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/2.0.0缓存

MemoryCacheOptions

image

Clock 顾名思义,是用来提供时间的一个成员,缓存里面大量用到了时间来判断缓存是否过时。异步

CompactOnMemoryPressure 已经被废弃,能够不用管分布式

ExpirationScanFrequency 过时扫描频率(默认为1分钟,能够理解为每过多久移除一次过时的缓存项)性能

SizeLimit 缓存大小限制(这属于一个说明性属性,并且单位也不是缓存数目,而是缓存真正占用的空间大小)线程

CompactionPercentage 压缩率(默认0.05,百分比)3d

Clock

初次见到的时候觉得是用来自定义 LocalTime,其实不是(固然要这么作也能够),在 MSCache 中只容许用 Utc 时间,可是为何既然都是 Utc 时间还要留这个扩展选项呢?orm

很简单,默认的当前时间是当前系统的当前时间,在一些对时间精度要求比较高的状况下就能够重写 Clock 来实现本身自定义的获取当前时间的逻辑。

ExpirationScanFrequency

缓存无非是一个字典表,当一些缓存项过时失效时候咱们须要移除字典表里面的内容。

然而准确的作到每一个缓冲项过时就进行移除是很是损失性能的(相似GC),因此 MSCache 提供了一个属性来设置,没间隔多久才进行一次过时缓存移除。

这个值默认为1分钟。

何时会进行过时缓存清理?

  1. 添加新的
  2. 获取缓存项
  3. 删除缓存项目
  4. 当有缓存项过时(经过过时回调)

这边就解释了上一节的最后为何没有回调输出。

由于MSCache里面没有使用定时器来进行过时扫描。

ps:缓存过时清理是一个异步方法也就是不会堵塞当前线程。

SizeLimit

这个属性在 MemoryCache 中几乎没有用,在 MemoryCache 中关于缓存项的大小默认都是null或0。

由于这个属性并非缓存项的数量,而是缓存真正占用的空间大小,如这个缓存项占用了多少内存。

然而在.NET中计算一个对象所占用的内存是很难且损耗性能的,因此在 MemoryCache 中这个属性几乎能够看作没有。

固然你能够经过手动设置缓存项的Size来启用相关功能。这边咱们只简单说明,详细讲解会在后面的分布式缓存中进行说明。

这个属性的做用是:当全部缓存大小超过这个值的时候进行一次缓存压缩。

CompactionPercentage

当内存大小超过 SizeLimit 时候进行压缩的比率,默认值是0.05,也就是百分之5。

具体的计算方式是

获得剩余的缓存大小 SizeLimit * 1 – CompactionPercentage

获得须要压缩的大小 CurrentSize  –  (SizeLimit * 1 – CompactionPercentage)

缓存的清理优先级

image

这时候就牵扯到 CacheEntry 中的 Priority 属性了,当发生这种状况的时候 MSCache 会按如下优先级进行压缩处理

  1. Low
  2. Normal
  3. High

为何没有  NeverRemove ?由于 NeverRemove 永远不会在超过 SizeLimt 时候进行清理。

那么当缓存大小超过SizeLimit时,MSCache会

先清理Low优先级的缓存项(无论是否过时)

再清理Normal优先级的缓存项(无论是否过时)

继续清理High优先级的缓存项(无论是否过时)

CacheEntry 默认的 优先级为:Normal。

写在最后

今天介绍了一些 MSCache 的内部机制,后续会讲一下 缓存域 和 一些小技巧。

.NET技术栈QQ群:384413261(点击加入 .NET Group

相关文章
相关标签/搜索