徐曉思
摘要:對于使用數據庫存儲數據的系統而言,硬盤較慢的讀取速度極大的限制了系統整體性能的提高。內存緩存機制將常用的數據從數據庫緩存到內存中并實時調整緩存數據,有效的提高了數據的查詢效率,降低了系統的響應時間。
關鍵詞:內存緩存;.NET;命中率
中圖分類號:TP333 文獻標識碼:A 文章編號:1007-9416(2018)02-0139-05
1 引言
對于使用數據庫存儲數據的系統而言,面臨的主要問題是如何高效的查詢數據,而硬盤較慢的讀取速度極大的限制了系統整體性能的提高。由于數據庫存儲的數據量通常都比較大,如果一次性將所有數據全部緩存到內存中,會導致內存緊張甚至溢出,影響整個系統的性能和穩定性。因此,需要在.NET平臺上設計并實現一個內存緩存機制,將部分使用到的數據從數據庫緩存到內存中,并根據緩存項的命中情況自動調整緩存數據,以提高數據讀取的效率。
2 設計
當有數據讀取請求的時候,首先檢查是否命中,即要讀取的數據是否在緩存中。如果命中,則直接讀取緩存中的數據進行使用,并更新緩存的狀態。如果數據不在緩存中,則首先讀取數據庫中的數據進行使用,然后將數據添加到緩存中。為了防止內存溢出,在程序中對緩存數據的數量設置了上限。當需要將數據添加到緩存中的時候,首先會檢查緩存是否已滿,如果緩存已滿,則根據清理算法對緩存進行清理后,再將新的數據添加到緩存中。數據讀取的流程圖如圖1所示。
為了提高命中率,在有數據庫寫入操作的時候,同樣需要更新緩存中的數據。當有數據庫寫入請求的時候,首先將數據寫入到數據庫,然后檢查是否命中,即要寫入的數據是否在緩存中。如果命中,則更新緩存項的數據和狀態。如果沒有命中,則需要將數據添加到緩存中。同樣,在添加的時候需要首先檢查緩存是否已滿,如果已滿則需要首先清理緩存后,再將新的數據添加到緩存中。數據寫入的流程圖如圖2所示。
內存緩存機制使用特定的緩存清理算法,緩存項中除了記錄數據,還記錄了該項的首次命中時間FirstTime(添加到緩存中的時間)、最后命中時間LastTime(最后一次被讀取或修改的時間)以及命中次數HitCount,并從以下四個角度去設計緩存清理算法:
(1)命中次數:對內存中所有緩存項按照HitCount進行排序,清理所有HitCount低于閾值的緩存項。
(2)最后命中時間:對內存中所有的緩存項按照LastTime進行排序,清理所有LastTime早于閾值的緩存項。
(3)平均命中周期:根據當前時間CurrentTime計算出緩存項的平均命中周期AveragePeriod并排序,清理所有AveragePeriod高于閾值的緩存項,計算公式為AveragePeriod=(CurrentTime-FirstTime)/HitCount。
(4)首次命中時間:如果前三種算法都未生效,則對內存中所有的緩存項按照FirstTime進行排序,清理FirstTime最早的那一項。
所有的閾值都可以在配置文件中進行設置。根據不同的部署環境設置不同的閾值能夠有效的保證緩存的命中率和清理算法的效率。
3 實現
內存緩存機制依靠CacheItem、CacheGroup和CacheManager這三個類來實現,類之間的關系如圖3所示。
CacheItem是緩存項在代碼中的實現,用來存儲緩存的內容。同時,該類還包含與命中有關的屬性,并提供了獲取和更新緩存內容的方法。
CacheItem包含以下私有屬性:
(1)id:緩存項的唯一標識符,String類型。CacheManager必須通過id才能在CacheGroup中找到對應的緩存項,這個屬性在CacheItem創建的時候被賦值,并且在緩存項的生命周期中始終保持不變。因此,該屬性通過只讀公有字段Id開放給外部讀取,但是不能被修改。
(2)content:用于存儲緩存的內容,這個屬性是Object類型的,因此可以存儲.NET中的任何對象。由于對content的讀取和修改會引起該緩存項命中相關屬性的變化,因此外部無法直接操作該屬性,必須通過CacheItem提供的方法來對內容進行讀取和修改。
(3)hitCount:命中次數,Integer類型。該屬性記錄緩存項的命中次數,在緩存內容被讀取或修改的時候會自動增長,因此通過只讀公有字段HitCount提供給外部讀取,但是不能被修改。
(4)firstTime:首次命中時間,DateTime類型。該屬性記錄緩存項添加到緩存中的時間,在CacheItem創建的時候被賦值,并且在緩存項的生命周期中始終保持不變。因此,該屬性通過只讀公有字段FirstTime開放給外部讀取,但是不能被修改。
(5)lastTime:最后命中時間,DateTime類型。該屬性記錄緩存項最后一次被讀取或修改的時間,在緩存內容被讀取或修改的時候會自動更新,因此通過只讀公有字段LastTime提供給外部讀取,但是不能被修改。
除此之外,CacheItem還包含一個只讀公有字段Average Period,該字段根據公式計算緩存項的平均命中周期,在每次被讀取的時候自動進行計算。
CacheItem的構造函數包括兩個參數id和content,用于在創建的時候屬于緩存項的唯一標識符和內容。
CacheItem包含以下兩個公有方法:
(1)RetrieveContent:該方法用于返回緩存項的內容,并自動更新lastTime和hitCount兩個私有屬性。
(2)UpdateContent:該方法包含一個Object類型的參數,用于更新緩存項的內容,并自動更新lastTime和hitCount兩個私有屬性。
CacheItem的類圖如圖4所示。
CacheGroup是緩存項的集合,繼承自KeyedCollection
CacheGroup的類圖如圖5所示。
CacheManager用于管理CacheGroup及其中的所有CacheItem。該類使用單實例模式,將構造函數私有化,僅在首次被調用的時候私有的創建唯一的實例instance,并通過只讀公有字段Instance發布給外部使用。
CacheManager包含以下私有屬性:
(1)cacheGroup:CacheGroup類的對象,用于存儲CacheItem。
(2)max:Integer類型,表示cacheGroup中緩存項的數量上限。當緩存項達到數量上限的時候,如果要再添加緩存項,則首先需要對cacheGroup進行清理。
(3)clearStrategies:List
(4)defaultStrategy:ClearStrategy類型,包含默認的緩存清理策略。
CacheManager包含以下私有方法:
(1)CheckCapacity:檢查cacheGroup中的緩存項是否達到數量上限。
(2)ClearCache:調用緩存清理策略清理緩存項。
(3)CreateCache:添加緩存項。在將緩存項添加到cacheGroup之前,會先調用CheckCapacity檢查緩存項數量,如果已經達到上限,則調用ClearCache方法清理緩存。
(4)DeleteCache:刪除緩存項。
CacheManager包含以下公有方法:
(1)Start:該方法用于啟動CacheManager,包含兩個參數max和clearStrategies,分別用來設置緩存項的數量上限以及用到的緩存清理策略。
(2)Stop:該方法用于在程序退出的時候關閉CacheManager,釋放占用的內存。
(3)RetrieveContent:根據Id提供對應緩存項的內容。該方法有兩個參數,一個是查詢的Id,另一個是用out關鍵字修飾的Object對象content,該對象會在方法結束的時候和返回值一起返回給調用者,返回值的類型是Boolean。如果有緩存項命中,則將命中的內容賦值給content并返回True,否則將content賦為空值并返回False。
(4)UpdateContent:該方法包含兩個參數id和content,用于更新id對應緩存項的內容。如果根據id無法命中緩存項,則調用CreateCache方法添加緩存項。
CacheManager的類圖如圖6所示。
CacheManager、CacheGroup和CacheItem只負責緩存讀寫的邏輯,緩存清理的邏輯由緩存清理策略實現。緩存清理策略的實現類圖如圖7所示。
抽象類ClearStrategy是所有緩存策略類的基類,該類實現了IClearStrategy接口的SetThreshold和Clear方法,并擴展了RemoveItems和RemoveItem方法,為子類實現了設置閾值和刪除緩存項的功能。ClearStrategy定義了一個抽象方法GetOutdatedItems,這個方法返回List
4 測試
內存緩存機制的測試基于應用了該機制的智能會議系統,并包括以下兩個部分:
(1)緩存命中率測試:按照一個中等規模會議室(30到50人)設置數據量和緩存參數,對緩存命中率進行測試,測試的結果如圖8所示。根據測試結果可以得到,命中率在測試初期較低,隨后快速上升,在300次請求后增速減緩,在850次請求后趨于穩定。穩定后的命中率在66%左右,即平均每3次數據讀取請求可以命中2次,只有1次需要讀取數據庫。
(2)系統響應時間測試:在內存緩存機制開啟和關閉兩種情況下分別對系統響應時間進行測試,并對兩組響應時間進行比較。兩種情況下系統響應時間測試的結果如表1所示。從表中可以看出,內存緩存機制在開啟情況下的響應時間明顯低于關閉情況。
5 結語
本文基于.NET平臺討論了內存緩存機制的設計、實現及應用效果的測試。從測試結果可以看到,內存緩存機制在命中率方面有不錯的表現,有效的提高了數據的查詢效率,降低了系統的響應時間,實現了設計的目標。
參考文獻
[1]常廣炎.Memcached分布式緩存系統的應用[J].電腦編程技巧與維護,2017,(07):24-25.
[2]邢蕾.內存緩存技術在門戶網站開發中的應用研究[J].山東工業技術,2016,(20):152-153.
[3]胡嘉瑜,華蓓.基于APU的內存鍵值緩存系統[J].電子技術,2016,45(09):54-59.
[4]石磊,黃高攀,喬雄.基于內存數據庫的索引算法研究[J].信息技術,2016,(11):139-142.
[5]許春聰,劉釗,文海雄,黃忠主,鄭強.基于內存的數據存儲技術研究[J].科技與創新,2018,(02):19-21.