擁抱.NET Core系列:MemoryCache 快取過期

KAnts發表於2018-02-28

在上一篇”擁抱.NET Core系列:MemoryCache 初識”中我們基本瞭解了快取的新增、刪除、獲取,那麼今天我們來看看快取的過期機制。這裡和上篇一樣將把“Microsoft.Extensions.Caching.Memory”簡稱為MSCache。

MSCache專案

MSCache目前最新的正式版是 2.0.0,預覽版是2.1.0,會與.NETCore 2.1一起釋出。本篇用了2.0.0版本

開源在GitHub上,倉庫地址是:https://github.com/aspnet/Caching

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

MSCache提供的過期方式

從原始碼來說,MSCache提供了以下三種快取過期的方式

  1. 絕對到期(指定在一個固定的時間點到期)
  2. 滑動到期(在一個時間長度內沒有被命中則過期)
  3. 到期Token(自定義過期)

下面我們來一一看看這些方式。

絕對時間到期

image

絕對到期非常的簡單,MS提供了一個擴充套件方法 “SetAbsoluteExpiration” 用來設定絕對到期時間。

image

這邊的第一個方法定義中的 relative 是指從當前時間度過這麼久的時間之後過期,類似 DateTime.Now.Add(relative)。

為什麼說類似呢?

因為每個國家地區的時間可能不一致,MSCache預設使用了UTC時間,這個時間可以在options進行修改,後面在做介紹。

滑動時間到期

image

除了前兩次迭代滿足2秒內命中快取,剩餘的3次迭代無法滿足2秒內命中,所以從第三次迭代開始快取項都會過期。

自定義過期策略

很多時候我們的快取過期條件並不是只有時間,比如我們對一個檔案內容進行了快取,當檔案變動的時候需要重新載入檔案更新快取。再比如我們快取了使用者資訊,在一個bus上接收到了使用者資訊變動後清除使用者快取並重新快取使用者。

MS為我們提供了一個非常簡單的自定義過期策略。

MS把這個過期策略使用一個介面 IChangeToken 來暴露。下面我們來看看 IChangeToken。

IChangeToken

IChangeToken不完全為MS而生,而是一個基礎包裡面的介面,所以在理解這個介面的時候儘量不要帶入快取來考慮。

image

HasChanged 顧名思義,用來返回是否發生了變更,在MSCache中如果返回了true則快取項將會失效。

ActiveChangeCallbacks 一個有點玄學的屬性,該屬性更多是一種描述,字面意思是該token是否會啟用回撥,取決於IChangeToken實現者的邏輯,如果這個值返回false則不要期望通過IChangeToken的RegisterChangeCallback來達到發生變更的時候有回撥通知。

RegisterChangeCallback 註冊一個回撥,當變更發生時執行,一般配合ActiveChangeCallbacks來達成。

一個約束並不是強制

ActiveChangeCallbacks 為 true 時通過RegisterChangeCallback 註冊的回撥會在發生變更時被回撥執行,反之相反。

MS其它元件實現的IChangeToken

  1. CancellationChangeToken (一個對CancellationToken的包裝)
  2. CompositeChangeToken (組合ChangeToken,可以將多個ChangeToken包裝成一個Token)
  3. ConfigurationReloadToken (配置重新載入Token,來自MS.Configuration元件)
  4. PollingFileChangeToken (通過輪訓來監控檔案變更)
  5. PollingWildCardChangeToken (通過輪訓來監控檔案變更,這個是支援萬用字元的)
  6. ……

快取一個檔案,並在檔案變化時候更新快取內容

image

手動過期快取

image

ChangeToken的一次性

恩,妥妥的輸出 1 1 2 2?

image

實際輸出結果 1 1 2 3

為什麼?

因為我們之前講到ChangeToken是通過HasChanged來判斷快取是否過期的。

在這邊我們呼叫了cts的Cancel,那麼無論如何HasChanged後續都會是true,因為cts的Cancel是不可逆的。

正確的做法

image

這邊正確的做法只是強調,ChangeToken是一次性的,具體如何達到這個目的大家可以自由發揮。

自定義一個ChangeToken,噹噹前時間的分數為偶數時候過期

image

image

過期策略組合拳

上面介紹了MSCache中的過期策略,但都是單獨使用的,其實這些過期策略可以混合使用。

比如指定 1個小時後到期或者10分鐘內沒有命中到期。

image

IChangeToken當然也是可以的。

這邊的過期策略是隻要啟動一個條件達成那麼這個快取就是無效的。

快取過期回撥

很多時候我們希望快取過期之後能做一些事情,比如重新寫入快取等等,MSCache提供了這樣的機制。

使用回撥相關的定義

image

image

image

示例

image

寫在最後

image

大家思考一下這段程式碼為什麼會沒有回撥輸出?

本篇主要講了MSCache中快取過期的幾種使用方式和擴充套件方式。下一篇會介紹下MSCache中的一些執行機制,比如上面的程式碼為何沒有輸出?如何清除一組快取等等。

.NET技術棧QQ群:384413261(點選加入 .NET Group

相關文章