<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4256字,需瀏覽 9分鐘

           ·

          2021-02-03 07:58


          背景

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

          解決方案

          ? ? 1、設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期。

          ? ? 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)                {                    // 取得每個(gè) Key專(zhuān)屬的 lock object;若同時(shí)有多個(gè) thread要求相同資料,只會(huì)(到資料庫(kù))查第一次,剩下的從 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(string key, Func 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,強(qiáng)制重查 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(serialize); } else { return result; } } } catch { return getDataWork(); } }

          總結(jié)說(shuō)明

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

            T result = CacheObject[key] as T;

          ? 2、緩存中沒(méi)有數(shù)據(jù),第1個(gè)進(jìn)入的線程,獲取鎖并從數(shù)據(jù)庫(kù)去取數(shù)據(jù),沒(méi)釋放鎖之前,其他并行進(jìn)入的線程會(huì)等待,再重新去緩存取數(shù)據(jù)。這樣就防止都去數(shù)據(jù)庫(kù)重復(fù)取數(shù)據(jù),重復(fù)往緩存中更新數(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、取得每個(gè) Key專(zhuān)有的 lock object;若同時(shí)有多個(gè) thread要求相同資料,只會(huì)(到數(shù)據(jù)庫(kù))查第一次,剩下的從 cache讀取。

          ? ? ? ? ? ? ? ? ? ?

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



          往期精彩回顧




          【推薦】.NET Core開(kāi)發(fā)實(shí)戰(zhàn)視頻課程?★★★

          .NET Core實(shí)戰(zhàn)項(xiàng)目之CMS 第一章 入門(mén)篇-開(kāi)篇及總體規(guī)劃

          【.NET Core微服務(wù)實(shí)戰(zhàn)-統(tǒng)一身份認(rèn)證】開(kāi)篇及目錄索引

          Redis基本使用及百億數(shù)據(jù)量中的使用技巧分享(附視頻地址及觀看指南)

          .NET Core中的一個(gè)接口多種實(shí)現(xiàn)的依賴(lài)注入與動(dòng)態(tài)選擇看這篇就夠了

          10個(gè)小技巧助您寫(xiě)出高性能的ASP.NET Core代碼

          用abp vNext快速開(kāi)發(fā)Quartz.NET定時(shí)任務(wù)管理界面

          在ASP.NET Core中創(chuàng)建基于Quartz.NET托管服務(wù)輕松實(shí)現(xiàn)作業(yè)調(diào)度

          現(xiàn)身說(shuō)法:實(shí)際業(yè)務(wù)出發(fā)分析百億數(shù)據(jù)量下的多表查詢(xún)優(yōu)化

          關(guān)于C#異步編程你應(yīng)該了解的幾點(diǎn)建議

          C#異步編程看這篇就夠了


          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日免费视频 | 激情五月毛片 | 日本精品18禁 | 精品人妻无码一区二区三区91 | 麻豆传媒一区二区在线观看 |