日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

巧用lock解决缓存击穿的解决方案

發(fā)布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 巧用lock解决缓存击穿的解决方案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

背景

緩存擊穿是指緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)(一般是緩存時間到期),這時由于并發(fā)用戶特別多,同時讀緩存沒讀到數(shù)據(jù),又同時去數(shù)據(jù)庫去取數(shù)據(jù),引起數(shù)據(jù)庫壓力瞬間增大,造成過大壓力。

解決方案

? ? 1、設置熱點數(shù)據(jù)永遠不過期。

? ? 2、加互斥鎖,互斥鎖參考代碼如下:

? ? ? ? ?2.1、根據(jù)key生成object()

private static object GetMemoryCacheLockObject(string key){string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);lock (CacheObject){var lockObject = CacheObject[cacheLockKey];if (lockObject == null){// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取lockObject = new object();CacheObject.Set(cacheLockKey,lockObject,new System.Runtime.Caching.CacheItemPolicy(){AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(10)});}return lockObject;}}

2.2、lock住GetMemoryCacheLockObject(key)

public T Get<T>(string key, Func<T> getDataWork, TimeSpan absoluteExpireTime, bool forceRefresh = false, bool returnCopy = true) where T : class{try{lock (GetMemoryCacheLockObject(key)){/* System.ArgumentNullException: Value cannot be null. at System.Threading.Monitor.Enter(Object obj) at BQoolCommon.Helpers.Cache.MemoryCacheLayer.Get[T](String key, Func`1 getDataWork, TimeSpan absoluteExpireTime, Boolean forceRefresh, Boolean returnCopy) in D:\Source\BQoolCommon\BQoolCommon.Helpers\Cache\MemoryCacheLayer.cs:line 46*/T result = CacheObject[key] as T;if (result != null && forceRefresh){// 是否清除Cache,強制重查result = null;}if (result == null){//執(zhí)行取得資料的委派作業(yè)result = getDataWork();if (result != null){Set(key, result, absoluteExpireTime);}}if (returnCopy){//複製一份新的參考string serialize = JsonConvert.SerializeObject(result);return JsonConvert.DeserializeObject<T>(serialize);}else{return result;}}}catch{return getDataWork();}}

總結說明

1、緩存中有數(shù)據(jù),直接走下述代碼就返回結果了

T result = CacheObject[key] as T;

? 2、緩存中沒有數(shù)據(jù),第1個進入的線程,獲取鎖并從數(shù)據(jù)庫去取數(shù)據(jù),沒釋放鎖之前,其他并行進入的線程會等待,再重新去緩存取數(shù)據(jù)。這樣就防止都去數(shù)據(jù)庫重復取數(shù)據(jù),重復往緩存中更新數(shù)據(jù)情況出現(xiàn)。

try{lock (GetMemoryCacheLockObject(key)){/* System.ArgumentNullException: Value cannot be null. at System.Threading.Monitor.Enter(Object obj) at BQoolCommon.Helpers.Cache.MemoryCacheLayer.Get[T](String key, Func`1 getDataWork, TimeSpan absoluteExpireTime, Boolean forceRefresh, Boolean returnCopy) in D:\Source\BQoolCommon\BQoolCommon.Helpers\Cache\MemoryCacheLayer.cs:line 46*/T result = CacheObject[key] as T;

3、取得每個 Key專有的 lock object;若同時有多個 thread要求相同資料,只會(到數(shù)據(jù)庫)查第一次,剩下的從 cache讀取。

? ? ? ? ? ? ? ? ? ?

string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);lock (CacheObject){var lockObject = CacheObject[cacheLockKey];if (lockObject == null){// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取lockObject = new object();

總結

以上是生活随笔為你收集整理的巧用lock解决缓存击穿的解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。