成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

巧用lock解決緩存擊穿的解決方案

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

[[379540]]

本文轉載自微信公眾號「UP技術控」,作者conan5566  。轉載本文請聯系UP技術控公眾號。 

背景

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

解決方案

1、設置熱點數據永遠不過期。

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

2.1、根據key生成object()

  1. private static object GetMemoryCacheLockObject(string key
  2.         { 
  3.             string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key); 
  4.             lock (CacheObject) 
  5.             { 
  6.                 var lockObject = CacheObject[cacheLockKey]; 
  7.                 if (lockObject == null
  8.                 { 
  9.                     // 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取 
  10.                     lockObject = new object(); 
  11.                     CacheObject.Set
  12.                         cacheLockKey, 
  13.                         lockObject, 
  14.                         new System.Runtime.Caching.CacheItemPolicy() 
  15.                         { 
  16.                             AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(10) 
  17.                         } 
  18.                     ); 
  19.                 } 
  20.  
  21.                 return lockObject; 
  22.             } 
  23.         } 

2.2、lock住GetMemoryCacheLockObject(key)

  1. public T Get<T>(string key, Func<T> getDataWork, TimeSpan absoluteExpireTime, bool forceRefresh = false, bool returnCopy = truewhere T : class 
  2.         { 
  3.             try 
  4.             { 
  5.                 lock (GetMemoryCacheLockObject(key)) 
  6.                 { 
  7.                     /* 
  8. System.ArgumentNullException: Value cannot be null
  9. at System.Threading.Monitor.Enter(Object obj) 
  10. 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 
  11.                      */ 
  12.                     T result = CacheObject[keyas T; 
  13.  
  14.                     if (result != null && forceRefresh) 
  15.                     {// 是否清除Cache,強制重查 
  16.                         result = null
  17.                     } 
  18.  
  19.                     if (result == null
  20.                     { 
  21.                         //執行取得資料的委派作業 
  22.                         result = getDataWork(); 
  23.  
  24.                         if (result != null
  25.                         { 
  26.                             Set(key, result, absoluteExpireTime); 
  27.                         } 
  28.                     } 
  29.  
  30.                     if (returnCopy) 
  31.                     { 
  32.                         //複製一份新的參考 
  33.                         string serialize = JsonConvert.SerializeObject(result); 
  34.                         return JsonConvert.DeserializeObject<T>(serialize); 
  35.                     } 
  36.                     else 
  37.                     { 
  38.                         return result; 
  39.                     } 
  40.                 } 
  41.             } 
  42.             catch 
  43.             { 
  44.                 return getDataWork(); 
  45.             } 
  46.         } 

總結說明

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

  1. T result = CacheObject[keyas T; 

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

  1. try 
  2.             { 
  3.                 lock (GetMemoryCacheLockObject(key)) 
  4.                 { 
  5.                     /* 
  6. System.ArgumentNullException: Value cannot be null
  7. at System.Threading.Monitor.Enter(Object obj) 
  8. 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 
  9.                      */ 
  10.                     T result = CacheObject[keyas T; 

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

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

 

 

責任編輯:武曉燕 來源: UP技術控
相關推薦

2024-07-12 08:48:50

2018-11-12 11:12:46

2023-11-10 14:58:03

2020-03-05 09:09:18

緩存原因方案

2023-10-13 08:11:22

2019-10-08 16:05:19

Redis數據庫系統

2022-03-08 00:07:51

緩存雪崩數據庫

2023-07-19 07:51:43

Redis緩存高可用

2024-06-24 00:30:00

2023-10-30 07:56:46

Spring緩存

2018-12-03 11:59:42

Inventec解決方案

2018-12-03 12:13:21

Mellanox解決方案

2018-12-03 12:26:30

YADRO解決方案

2012-05-27 16:21:31

IDC華為

2018-12-03 12:17:27

Semptian解決方案

2025-02-04 17:40:44

2016-03-13 17:58:57

2011-11-30 13:08:55

企業防毒防毒方案拯救三

2009-03-05 10:38:00

2011-05-05 15:36:25

深信服廣域網加速
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美三级免费观看 | 国产不卡视频 | 中国黄色毛片视频 | 日韩免费网 | 亚洲一区二区在线 | 久久久91精品国产一区二区三区 | 国产一区二区 | 精品国产欧美一区二区 | 天天视频成人 | 国产区在线免费观看 | 激情小视频 | 亚洲一区在线播放 | 欧美一级免费看 | 国产精品乱码一区二区三区 | 一二区电影 | 婷婷丁香综合网 | av手机在线| 中文字幕一区在线观看视频 | 日韩在线观看网站 | 国产精品久久久久久久午夜片 | 久久99精品久久久久久国产越南 | 99精品久久| 精品久久不卡 | 国产黄色大片在线免费观看 | 日韩一级黄色片 | 久久精品亚洲成在人线av网址 | 国产区在线免费观看 | 久久一二区 | 国产综合在线视频 | 国产乱码精品1区2区3区 | 男女那个视频 | 精品国产aⅴ | 国产精品区二区三区日本 | 区一区二区三在线观看 | 日韩免费一二三区 | 国产婷婷在线视频 | 欧美一区二区二区 | 国产精品一区二区三区四区五区 | 欧美视频成人 | 国产成人精品综合 | 国产精品区一区二区三区 |