淺談 .NET Core 快取機制 (Cache)

快取機制 ( Cache )是在軟體開發過程中常使用的一種,簡易但有力的提升效能方法,將不會經常變動、或是不會更改的資料預先存進快取中,當下回需要這筆資料時便可直接至記憶體索取,不必再進到硬碟取資料或是重複進行操作運算,減少IO或讀取資料庫的次數,增加程式運行的效能。

快取適用於變動率低的資料,意即會刷新頻繁、例如當下的讀秒數據便不適合放入快取中。

快取機制 可分為三種,分別是:

  1. In-memory Cache:又稱為 In-process Cache ,特徵是在 single process 實作快取,當 process 結束時 cache  也一併結束。
  2. Persistenat In-process Cache :當要將快取內容備份至 process 之外時(例如 Files、或是存至資料庫…等等)稱之。此種 快取機制 的優點是即使重啟也不會遺失快取內容,適合在 process 需要進行頻繁重啟,或是快取內容的取得成本較高的情境使用。
  3. Distributed Cache :適合當使用者想將快取內容分享給數台機器(Server)使用的情境,將資料位置指向外部的儲存空間,當其中一台伺服器存取快取時,其它站台也能取用相同的內容。例如 Redis 服務即是一種應用範例。

 

我們可用 C# 實作一個簡單的快取功能:

程式碼範例

 

使用範例:

程式碼範例

 

以 userId 為鍵值,當想取出使用者的資料時,會優先尋找 process memory 內是否有對應之值,只有為初次存取的 ID 才會至資料庫撈取,節省時間及資源。

然而上面這份陽春的實作具有幾個問題:首先,這段程式碼並不具備執行緒安全(Thread-Safe)的條件,當將這段程式應用至多執行緒的程式時,可能會在動作未執行完畢即對使用中的共同變數進行插斷,進一步產生錯誤;其次,這段程式並未提供清除快取的功能,若不符合GC(Garbage Collector)條件則可能導致資料卡在記憶體中,資源無法被釋放。快取機制 應該提供清除功能的原因有幾項,包括:當快取內容需要進行更新,而無法刪除舊有資料可能產生一些結果上的問題,同時資料不斷累積在記憶體中最終將導致記憶體用罄;或是增加 GC Pressure,導致效能變差。

為了避免上述狀況,一般在 快取機制 中會具備資料移除的相關規範,常見的可分為兩種:

  • Absolute Expiration:無論任何理由,當設定的期間一到就刪除資料,這類規範通常用於不常更動的快取資料。
  • Sliding Expiration:當快取經過一段時間沒有被取用,資料便會被清除。適用於經常需要更新的資料內容。

另外還有以資料大小限制作為規範標準等等種類,在此篇不再多提。

 

談了這些快取的基礎條件,看似眉角不少,但其實開發者不必樣樣自己造輪子,以 C# 為例,微軟已有提供的方便的快取處理套件供開發者取用,目前可應用在 .NET Core 環境上的主要有兩種:System.Runtime.Caching 及 Microsoft.Extensions.Caching.Memory,其中官方推薦在 .NET Core 環境使用後者的整合性更佳。

例如上述的快取實作範例,引用 Microsoft.Extensions.Caching.Memory 後可改為:

程式碼範例

使用範例則同上、兩個範例看似相似,但使用套件的版本具備 Thread-Safe 的條件,同時 Memory Cache 這個型別根據上述的規範提供清除資料的功能,例如 SetAbsoluteExpiration、SetSlidingExpiration…等等函式,使用方法及其餘的更多套件應用可參閱官方提供的技術文件。快取為軟體開發中經常使用的一個小技巧,若使用不得當會伴隨著相當的風險,反之適當斟酌快取的使用則能大大地增進程式效能,是個原理簡單但強大的便利機制。

若想進一步了解C# 的快取套件、GC 記憶體管理等等資訊,可點閱以下參考資料連結:

 

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.caching.memory?view=aspnetcore-2.2

https://docs.microsoft.com/zh-tw/dotnet/api/system.runtime.caching?view=netframework-4.8

https://michaelscodingspot.com/

https://docs.microsoft.com/zh-tw/dotnet/api/system.gc?view=netframework-4.8

Comments

No comments yet. Why don’t you start the discussion?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料