在AspNetCore 中 使用Redis實現分散式緩存

来源:https://www.cnblogs.com/szlblog/archive/2018/05/16/9045209.html
-Advertisement-
Play Games

AspNetCore 使用Redis實現分散式緩存 上一篇講到了,Core的內置緩存:IMemoryCache,以及緩存的基礎概念。本篇會進行一些概念上的補充。 本篇我們記錄的內容是怎麼在Core中使用Redis 和 SQL Server 實現分散式緩存。 一、文章概念描述 分散式緩存描述: 分散式 ...


AspNetCore 使用Redis實現分散式緩存

上一篇講到了,Core的內置緩存:IMemoryCache,以及緩存的基礎概念。本篇會進行一些概念上的補充。

 

本篇我們記錄的內容是怎麼在Core中使用Redis 和 SQL Server 實現分散式緩存。

一、文章概念描述

分散式緩存描述

分散式緩存重點是在分散式上,相信大家接觸過的分散式有很多中,像分散式開發,分散式部署,分散式鎖、事物、系統 等有很多。使我們對分散式本身就有一個很明確的認識,分散式就是有多個應用程式組成,可能分佈在不同的伺服器上,最終都是在為web端提供服務。

分散式緩存有以下幾點優點:

(1)所有的Web伺服器上的緩存數據都是相同的,不會因為應用程式不同,伺服器的不同導致緩存數據的不一樣。

(2)緩存的是獨立的不受Web伺服器的重新啟動或被刪除添加的影響,也就是說這些Web的改變不到導致緩存數據的改變。

 

傳統的單體應用架構因為用戶的訪問量的不高,緩存的存在大多數都是存儲用戶的信息,以及一些頁面,大多數的操作都是直接和DB進行讀寫交互,這種架構簡單,也稱為簡單架構,

傳統的OA項目比如ERP,SCM,CRM等系統因為用戶量不大也是因為大多數公司業務的原因,單體應用架構還是很常用的架構,但是有些系統隨著用戶量的增加,業務的擴張擴展,導致DB的瓶頸的出現。

以下我所瞭解到的關於這種情況的處理有以下兩種

(1):當用戶訪問量不大,但是讀寫的數據量很大的時候,我們一般採取的是,對DB進行讀寫分離、一主多從、對硬體進行升級的方式來解決DB瓶頸的問題。

  這樣的缺點也同樣純在:

1、用戶量大的時候怎麼辦?,

2、對於性能的提升有限,

3、性價比不高。提升一點性能就需要花費很多代價,(打個比方,現在的I/O吞吐量是0.9的需要提升到1.0,我們在增加機器配置的情況下這個價格確實很可觀的)

2):當用戶訪問量也增加的時候,我們就需要引入緩存了來解決了,一張圖描述緩存的大致的作用。

 

 

 

 

緩存主要針對的是不經常發生改變的並且訪問量很大的數據,DB資料庫可以理解為只作為數據固化的或者只用來讀取經常發生改變的數據,上圖中我沒有畫SET的操作,就是想特意說明一下,緩存的存在可以作為一個臨時的資料庫,我們可以通過定時的任務的方式去同步緩存和資料庫中的數據,這樣做的好處是可以轉移資料庫的壓力到緩存中。

 

緩存的出現解決了資料庫壓力的問題,但是當以下情況發生的時候,緩存就不在起到作用了,緩存穿透、緩存擊穿緩存雪崩這三種情況。

 

緩存穿透:我們的程式中用緩存的時候一般採取的是先去緩存中查詢我們想要的緩存數據,如果緩存中不存在我們想要的數據的話,緩存就失去了做用(緩存失效)我們就是需要伸手向DB庫去要數據,這個時候這種動作過多資料庫就崩潰了,這種情況需要我們去預防了。比如說:我們向緩存獲取一個用戶信息,但是故意去輸入一個緩存中不存在的用戶信息,這樣就避過了緩存,把壓力重新轉移到數據上面了。對於這種問題我們可以採取,把第一次訪問的數據進行緩存,因為緩存查不到用戶信息,資料庫也查詢不到用戶信息,這個時候避免重覆的訪問我們把這個請求緩存起來,把壓力重新轉向緩存中,有人會有疑問了,當訪問的參數有上萬個都是不重覆的參數並且都是可以躲避緩存的怎麼辦,我們同樣把數據存起來設置一個較短過期時間清理緩存。

緩存擊穿:事情是這樣的,對於一些設置了過期時間的緩存KEY,在過期的時候,程式被高併發的訪問了(緩存失效),這個時候使用互斥鎖來解決問題,

互斥鎖原理:通俗的描述就是,一萬個用戶訪問了,但是只有一個用戶可以拿到訪問資料庫的許可權,當這個用戶拿到這個許可權之後重新創建緩存,這個時候剩下的訪問者因為沒有拿到許可權,就原地等待著去訪問緩存。

 

永不過期:有人就會想了,我不設置過期時間不就行了嗎?可以,但是這樣做也是有缺點的,我們需要定期的取更新緩存,這個時候緩存中的數據比較延遲。

    緩存雪崩是指多種緩存設置了同一時間過期,這個時候大批量的數據訪問來了,(緩存失效)資料庫DB的壓力又上來了。解決方法在設置過期時間的時候在過期時間的基礎上增加一個隨機數儘可能的保證緩存不會大面積的同事失效。

二、文章內容實現

AspNetCore中使用  Redis實現緩存:

 

在項目中引用:using Microsoft.Extensions.Caching.Distributed; 使用IDistributedCache

IDistributedCache 介面

IDistributedCache介面包含同步和非同步方法。 介面允許在分散式緩存實現中添加、檢索和刪除項。 IDistributedCache介面包含以下方法:

GetGetAsync

採用字元串鍵並以byte[]形式檢索緩存項(如果在緩存中找到)。

SetSetAsync

使用字元串鍵向緩存添加項byte[]形式)。

RefreshRefreshAsync

根據鍵刷新緩存中的項,並重置其可調過期超時值(如果有)。

RemoveRemoveAsync

根據鍵刪除緩存項。

以下是我的代碼封裝DistributedCache類名:主要針對IDistributedCache中非非同步方法,非同步只寫了一個簡單的例子:

1、Get()獲取緩存

 

 /// <summary>
        /// 獲取緩存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object Get(string key)
        {
            string ReturnStr = "";
            if (!string.IsNullOrEmpty(key))
            {
                if (Exists(key))
                {
                    ReturnStr = Encoding.UTF8.GetString(_cache.Get(key));
                }
            }
            return ReturnStr;
        }
View Code

 

2GetAsync()非同步獲取緩存
/// <summary>
        /// 使用非同步獲取緩存信息
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<object> GetAsync(string key)
        {
            string ReturnString = null;
            var value = await _cache.GetAsync(key);
            if (value != null)
            {
                ReturnString = Encoding.UTF8.GetString(value);
            }
            return ReturnString;
        }
View Code

3Set()設置或添加緩存

 /// <summary>
        /// 添加緩存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Add(string key, object value)
        {
            byte[] val = null;
            if (value.ToString() != "")
            {
                val = Encoding.UTF8.GetBytes(value.ToString());
            }
            DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
            //設置絕對過期時間 兩種寫法
            options.AbsoluteExpiration = DateTime.Now.AddMinutes(30);
            // options.SetAbsoluteExpiration(DateTime.Now.AddMinutes(30));
            //設置滑動過期時間 兩種寫法
            options.SlidingExpiration = TimeSpan.FromSeconds(30);
            //options.SetSlidingExpiration(TimeSpan.FromSeconds(30));
            //添加緩存
            _cache.Set(key, val, options);
            //刷新緩存
            _cache.Refresh(key);
            return Exists(key);
        }
View Code

4、Remove()刪除緩存

 

 /// <summary>
        /// 刪除緩存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Remove(string key)
        {
            bool ReturnBool = false;
            if (key != "" || key != null)
            {
                _cache.Remove(key);
                if (Exists(key) == false)
                {
                    ReturnBool = true;
                }
            }
            return ReturnBool;
        }
View Code

 

5、修改緩存

  /// <summary>
        /// 修改緩存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Modify(string key, object value)
        {
            bool ReturnBool = false;
            if (key != "" || key != null)
            {
                if (Remove(key))
                {
                    ReturnBool = Add(key, value.ToString());
                }

            }
            return ReturnBool;
        }
View Code

6、驗證緩存是否存在

/// <summary>
        /// 驗證是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Exists(string key)
        {
            bool ReturnBool = true;
            byte[] val = _cache.Get(key);
            if (val == null || val.Length == 0)
            {
                ReturnBool = false;
            }
            return ReturnBool;
        }
View Code

三、文章內容調用

 

以上是代碼的封裝:下麵是在AspnetCore中調用

1、首先安裝Redis緩存:這個網上找個下載安裝就行

2、然後下載安裝:客戶端工具:RedisDesktopManager(方便管理)

3、在我們的項目Nuget中 引用 Microsoft.Extensions.Caching.Redis

 

 4、在項目啟動Setup.cs中註冊:Redis服務:代碼如下

 

public void ConfigureServices(IServiceCollection services)
        {
            //將Redis分散式緩存服務添加到服務中
            services.AddDistributedRedisCache(options =>
            {
                //用於連接Redis的配置  Configuration.GetConnectionString("RedisConnectionString")讀取配置信息的串
                options.Configuration = "localhost";// Configuration.GetConnectionString("RedisConnectionString");
                //Redis實例名RedisDistributedCache
                options.InstanceName = "RedisDistributedCache";
            });
            services.AddMvc();
        }
View Code

 

5、我是用CoreAPI來寫的 控制器中代碼如下:

1)先實例對象

  private DistributedCache _Cache;

        /// <summary>
        ///   構造註入
        /// </summary>
        /// <param name="Cache"></param>
        public ValuesController(IDistributedCache Cache)
        {
            _Cache = new DistributedCache(Cache);
        }
View Code

2)調用DistributedCache 類中的方法 代碼如下:

 

[HttpGet("{id}")]
        public string Get(int id)
        {
            //添加
            bool booladd = _Cache.Add("id", "sssss");
            //驗證
            bool boolExists = _Cache.Exists("id");
            //獲取
            object obj = _Cache.Get("id");
            //刪除
            bool boolRemove = _Cache.Remove("id");
            //修改
            bool boolModify = _Cache.Modify("id", "ssssssss"); 

            return obj.ToString();
        }
View Code

 

OK 結束,最後吐槽一下網上怎麼這麼多複製粘貼的,千篇一律    

     

          有不足之處 希望大家指出相互學習,

                                   轉載請註明出處 謝謝!

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 項目中經常碰到需要輸出的是json數據,使用JavaScriptSerializer轉換,以前老的方法如下。 JavaScriptSerializer jss = new JavaScriptSerializer(); jss.Serialize(obj); 這樣每次太麻煩了,而且每次有錯誤都會影響 ...
  • SliderView控制項 一、 樣式一 我們要實現上圖中的效果,需要如下的操作: 獲得和設置標簽視圖集合,打開集合編輯器,並點擊“添加”,分別填寫ResourceID屬性(菜單項圖片名稱),Text(菜單項文本),Value(內部值,不在界面上顯示),如圖1、圖 2; 圖 1設置界面1 圖 2設置界 ...
  • 使用.Net Core + NGINX部署到伺服器的時候,如果埠不是使用預設的80埠,在跳轉到登錄頁面時,URL中的埠丟失。 ...
  • 如何啟用功能: 開啟控制器的刷一次功能 下發卡許可權時標記該卡是否使用刷一次(或限次功能) 刷一次的功能表現 在單個控制器上,表現為刷1次後再刷時提示無許可權 啟用了"發送刷一次信號"後,通過網路UDP廣播向其它控制器通知,同組的其它控制器也提示無許可權 斷開023後,在021和023上各可以刷一次 斷開... ...
  • 需要說明的是這裡的大陸身份證識別並不是公安局聯網的識別,而是按國標GB 11643進行的驗證,所以其驗證結果只能說符合國標規範,但不能保證該身份證一定真實存在,如果你實際需求是希望身份證一定真實存在,那麼你可以在通過此類庫初步驗證後,再調用第三方(或牛逼的可以直連公安,畢竟所有的第三方其數據來源必定 ...
  • class Program { static void Main(string[] args) { List obj = new List(); obj.Add(new { aa=1,bb=1}); obj.Add(new { aa = 1, bb = 2 }); ... ...
  • 一、NuGet包 拼音:Install-Package PinYinConverterCore 簡體-繁體互轉:Install-Package TraditionalChineseToSimplifiedConverter 二、C#代碼 class Program { static void Mai ...
  • 全篇依據 C#高級編程(第9版) 內容記錄: 基礎知識C# 5.0 基礎 分為15章內容來介紹 核心C# 對象和類型 繼承 泛型 數組 運算符和類型強制轉換 委托和lambda表達式,事件 字元串和正則表達式 集合 LINQ 動態語言擴展 非同步編程 記憶體管理和指針 反射 錯誤和異常 在接下來的學習中 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...