透過ChangeMonitor實作多個網站同步快取

   目前公司有一個網站執行在Azure上,並將經常讀取的共用資料快取在記憶內。初期網站的負戴量還沒那麼大時,在快取資料上不會有什麼問題,但之後若成長到一定的程度時,網站勢必要作擴展,此時會造成快取的資料在多個Instance是不同步的。針對此找了幾個解決方案
  1. Azure Redis Cache:最多人使用,也是官方推薦使用,效能快,可以輕易作到多網站之間的快取共享。關於Redis更多請參考
    ps這適合較大的WebFarm使用,若你的擴展不會很多台的話,可以考慮使用第3個方法。
  2. Database Cache 在Nuget有一套件Ovicus.Caching實作了ObjectCache(.Net4.0新的快取類別請參考),將資料快取在資料庫內。這樣也可以達到多個網站的共享快取,但在效能會比軙慢了點,尤其在大量的快取存取下更明顯。
  3. 透過ChangeMonitor監控快取:此方案有別於上述兩個,不作共享快取,只作單機快取。透過監控的機制,在資料變更時,通知所有網站清除本身的In-Memory快取,再作資料的重新取得。

實作ChangeMonitor監控快取

   針對第3點的實作介紹,.NET 4.0新增的System.Runtime.Caching命名空間。ChangeMonitor為一抽象基底類別,可監控快取介質的狀態,判斷快取是否需要更新。內建相關實作HostFileChangeMonitor、SqlChangeMonitor。在Azure上無法使用HostFileChangeMonitor來達到我們要的需求,本篇使用SqlChangeMonitor實作。
  1. 建立資料表,並新增一筆資料。可以視為清除快取的開關,當資料更新時,在需要清除快取時,異動此欄位值。
    image
  2. 設定資料庫的資料異動通知
    image
  3. 新增類別MemoryCacheMonitor,實作SqlMonitor的通知機制
    image
  4. 接收SqlDependency的資料異動通知
    image
  5. 測試程式
    先按[Add Cache]2次,此時會有3筆資料顯示
    image
    按[Notify Monitor] 異動資料庫,並會引發異動通知作清除快取,接著再按[Show Cache] 此時Cache內只剩一筆資料。
    image

Summary

  透過快取監控機制的實作,提供了除了Redis Cache的另一選擇(至少不用多花一筆費用XD)。若不考慮快取資源的共享,在小規模的WebFarm下,此方法倒是個不錯的選擇。本篇使用的是資料庫來監控,國外也有人使用Azure Blob來作監控,有興趣可以參考此篇

完整範例下載


參考連結

http://www.codeproject.com/Articles/167282/NET-4-0-MemoryCache-with-SqlChangeMonitor

 

後記

經同事提醒,Azure不一定有支援Service Broker。查了一下....果然

http://feedback.azure.com/forums/217321-sql-database/suggestions/423275-enable-sql-service-broker-in-sql-azure

https://zh.wikipedia.org/wiki/Windows_Azure_SQL_Database

這個網誌中的熱門文章

[.NET Core] 將專案發行至IIS

[TFS] 分支與合併