擁抱.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

相關文章
相關標籤/搜索