NoSql之Redis系列(.Net Core)


一. 簡介

1. 什么是Redis?

  全稱“Remote Dictionary Server”,基於內存管理數據,它有多種數據結構(常用的5種),分別應對不同場景;它是單線程模型的,所以不會存在並發問題,數據不會出現中間狀態;對外提供:增刪改查、固化、集群等功能,包含0-15個數據存儲庫。

PS:Redis主要用來提升性能的,盡量不要作為數據的最終依據(當然可以配置高並發架構持久化存儲到硬盤)。

2. Redis優點

(1).支持 string、hash、set、sortedset、list、geo 等復雜的數據結構。

(2).高命中的數據運行時是在內存中,數據最終還是可以保存到磁盤中,這樣服務器重啟之后數據還在。

(3).服務器是單線程的,來自所有客戶端的所有命令都是串行執行的,因此不用擔心並發修改(串行操作當然還是有並發問題)的問題,編程模型簡單。

(4).支持消息訂閱/通知機制,可以用作消息隊列。

(5).Key、Value 最大長度允許512M。

  特別說明:Redis的單線程不用擔心並發指定是每個單一操作之間是單線程,比如客戶端同時發過來多個針對同一key的StringIncrement自增操作,Redis端是串行進行的,有先后,不會同時進行。 但是如果客戶端每個請求是一個組合操作,比如:先KeyExists,再KeyDelete;這個時候很可能第一個客戶端KeyExists的時候,數據是存在的,當它要KeyDelete,該數據已經被別的客戶端刪除了。

3.Redis缺點

(1) Redis 是單線程的,因此單個 Redis 實例只能使用一個CPU核,不能充分發揮服務器的性能。可以在一台服務器上運行多個 Redis 實例,不同實例監聽不同端口,再互相組成集群。

(2) 做緩存性能不如 Memcached;

4. 常用工具說明和下載

(1) Redis的Windows版本下載

  https://github.com/MicrosoftArchive/redis/tags, 目前最新版本【3.2.1】, .zip類型的是手動exe打開部署, .msi是自動部署成windows服務。

PS:Linux下的Redis已經到了5.x版本了

(2) .Net的兩個程序集

  a. StackExchange.Redis:免費.【推薦】 (目前最新版本:2.0.601),里面的每類方法基本上都有對應的異步方法

  b. ServiceStack.Redis:收費(1小時3600次請求限制),但可以破解,后面介紹

(3).可視化客戶端程序:RedisDesktopManager

5. 六大數據結構

(1).String:典型的key-value集合。

(2).Hash:一個key(hashid)對應,多個key-value集合。

(3).Set:一個key對應多個value,且value值不重復,且無序。

(4).SortedSet:一個key對應多個 member-score,member不重復。

(5).List:是一個雙向鏈表,可以左進、左出、右進、右出。

(6).Geo:用來保存興趣點(POI,point of interest)的坐標信息。可以實現計算兩 POI 之間的距離、獲取一個點周邊指定距離的 POI。

 

6.Windows版Redis包含文件介紹

(1). redis-server.exe:Redis的服務程序

(2). redis-cli.exe:連接當前Redis服務的客戶端

(3). redis.conf : redis相應配置

(4). redis-check-aof.exe:更新日志檢查

(5). dump.rdb:持久化到本地保存的數據庫文件

 

二. 基本使用

 前提:

  ①.管理員身份啟動Redis服務器【redis-server.exe】,打開可視化客戶端RedisDesktopManager進行查看。

  ②.通過Nuget給Utils層安裝程序集【StackExchange.Redis】,將Redis的兩個幫助類RedisHelp和RedisHelp2也放到該類,這里我們使用RedisHelp類。

分享RedisHelp相關類代碼

 1     /// <summary>
 2     /// Redis幫助類(寫法1)
 3     /// </summary>
 4     public class RedisHelp
 5     {
 6         private string _connectionString; //連接字符串
 7         private int _defaultDB; //默認數據庫
 8         private readonly ConnectionMultiplexer connectionMultiplexer;
 9 
10         /// <summary>
11         /// 構造函數
12         /// </summary>
13         /// <param name="connectionString"></param>
14         /// <param name="defaultDB">默認使用Redis的0庫</param>
15         public RedisHelp(string connectionString, int defaultDB = 0)
16         {
17             _connectionString = connectionString;
18             _defaultDB = defaultDB;
19             connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
20         }
21 
22         /// <summary>
23         /// 獲取數據庫
24         /// </summary>
25         /// <returns></returns>
26         public IDatabase GetDatabase()
27         {
28             return connectionMultiplexer.GetDatabase(_defaultDB);
29         }
30 
31     }
RedisHelp
 1      /// <summary>
 2     /// Redis幫助類(寫法2)
 3     /// </summary>
 4     public class RedisHelp2 : IDisposable
 5     {
 6         private string _connectionString; //連接字符串
 7         private string _instanceName; //實例名稱
 8         private int _defaultDB; //默認數據庫
 9         private ConcurrentDictionary<string, ConnectionMultiplexer> _connections;
10         public RedisHelp2(string connectionString, string instanceName, int defaultDB = 0)
11         {
12             _connectionString = connectionString;
13             _instanceName = instanceName;
14             _defaultDB = defaultDB;
15             _connections = new ConcurrentDictionary<string, ConnectionMultiplexer>();
16         }
17 
18         /// <summary>
19         /// 獲取ConnectionMultiplexer
20         /// </summary>
21         /// <returns></returns>
22         private ConnectionMultiplexer GetConnect()
23         {
24             return _connections.GetOrAdd(_instanceName, p => ConnectionMultiplexer.Connect(_connectionString));
25         }
26 
27         /// <summary>
28         /// 獲取數據庫
29         /// </summary>
30         /// <param name="configName"></param>
31         /// <param name="db">默認為0:優先代碼的db配置,其次config中的配置</param>
32         /// <returns></returns>
33         public IDatabase GetDatabase()
34         {
35             return GetConnect().GetDatabase(_defaultDB);
36         }
37 
38         public IServer GetServer(string configName = null, int endPointsIndex = 0)
39         {
40             var confOption = ConfigurationOptions.Parse(_connectionString);
41             return GetConnect().GetServer(confOption.EndPoints[endPointsIndex]);
42         }
43 
44         public ISubscriber GetSubscriber(string configName = null)
45         {
46             return GetConnect().GetSubscriber();
47         }
48 
49         public void Dispose()
50         {
51             if (_connections != null && _connections.Count > 0)
52             {
53                 foreach (var item in _connections.Values)
54                 {
55                     item.Close();
56                 }
57             }
58         }
59     }
RedisHelp2

1.直接通過Redis客戶端操作

  打開客戶端【redis-cli.exe】, 默認存儲的是0庫,可以通過命令set和get指定進行存儲和查詢,比如:【set fristName Y】和【get firstName】,如果要選擇2庫或3庫,可以通過指令【select 2】和【select 3】來進行。

補充:如果要連接別的服務器端,通過指令【 redis-cli.exe -h 127.0.0.1 -p 6379】

2.DotNet Core控制台操作

  實例化RedisHelp類,傳入連接字符串和默認數據庫,進行string類型的key-value存儲和查詢.

 (1). 客戶端讀取配置文件,並創建RedisHelp實例。 通過Nuget安裝程序集:【Microsoft.Extensions.Configuration】和【Microsoft.Extensions.Configuration.Json】

1 {
2   "RedisStr": {
3     "connectionString": "localhost:6379",
4     "defaultDB": 0
5   }
6 }
1             //讀取Redis的相關配置
2             var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
3             var Configuration = configurationBuilder.Build();
4             var _connectionString = Configuration["RedisStr:connectionString"]; //連接字符串
5             int _defaultDB = Convert.ToInt32(Configuration["RedisStr:defaultDB"]);  //默認數據庫
6             RedisHelp redis = new RedisHelp(_connectionString, _defaultDB);
7             var db = redis.GetDatabase();

 (2). 進行簡單的插入和查詢操作。

1 db.StringSet("name", "fk");
2 Console.WriteLine("插入成功");
3 string d1 = db.StringGet("name");
4 Console.WriteLine($"獲取成功,name的值為{d1}");

3.CoreMvc操作

  在類ConfigureServices中獲取Redis的配置並注冊RedisHelp單例類,然后在對應控制器中進行注入使用即可。RedisHelp注冊成單例類,然后在對應的控制器中進行注入,使用即可。這里再補充一種讀取配置文件的方式,利用IOptions<T>,詳見下面RedisHelp_Test類的注入。

 1      /// <summary>
 2     /// Redis幫助類(寫法1)
 3     /// </summary>
 4     public class RedisHelp
 5     {
 6         private string _connectionString; //連接字符串
 7         private int _defaultDB; //默認數據庫
 8         private readonly ConnectionMultiplexer connectionMultiplexer;
 9 
10         /// <summary>
11         /// 構造函數
12         /// </summary>
13         /// <param name="connectionString"></param>
14         /// <param name="defaultDB">默認使用Redis的0庫</param>
15         public RedisHelp(string connectionString, int defaultDB = 0)
16         {
17             _connectionString = connectionString;
18             _defaultDB = defaultDB;
19             connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
20         }
21 
22         /// <summary>
23         /// 獲取數據庫
24         /// </summary>
25         /// <returns></returns>
26         public IDatabase GetDatabase()
27         {
28             return connectionMultiplexer.GetDatabase(_defaultDB);
29         }
30 
31     }
RedisHelp
 1      /// <summary>
 2     /// 內容同RedisHelp相同,這里是為了測試另外一種配置文件讀取的方式
 3     /// </summary>
 4     public class RedisHelp_Test
 5     {
 6         private readonly IOptions<RedisSetting> _redisSetting;
 7         private readonly ConnectionMultiplexer _connectionMultiplexer;
 8 
 9         /// <summary>
10         /// 構造函數
11         /// </summary>
12         /// <param name="connectionString"></param>
13         /// <param name="defaultDB">默認使用Redis的0庫</param>
14         public RedisHelp_Test(IOptions<RedisSetting> redisSetting)
15         {
16             this._redisSetting = redisSetting;
17             _connectionMultiplexer = ConnectionMultiplexer.Connect(_redisSetting.Value.connectionString);
18         }
19 
20         /// <summary>
21         /// 獲取數據庫
22         /// </summary>
23         /// <returns></returns>
24         public IDatabase GetDatabase()
25         {
26             return _connectionMultiplexer.GetDatabase(_redisSetting.Value.defaultDB);
27         }
28     }
RedisHelp_Test
1 {
2   "RedisStr": {
3     "connectionString": "localhost:6379",
4     "defaultDB": 0
5   }
6 }
 1         public void ConfigureServices(IServiceCollection services)
 2         {
 3             //獲取Redis配置,注入RedisHelp單例對象
 4             {
 5                 var connectionString = Configuration["RedisStr:connectionString"];
 6                 int defaultDB = Convert.ToInt32(Configuration["RedisStr:defaultDB"]);
 7                 services.AddSingleton(new RedisHelp(connectionString, defaultDB));
 8             }
 9             //另外一種讀取Redis配置的方法
10             {
11                 services.AddOptions().Configure<RedisSetting>(Configuration.GetSection("RedisStr"));
12                 services.AddSingleton<RedisHelp_Test>();
13             }
14             services.AddControllersWithViews();
15         }
 1  public class HomeController : Controller
 2     {
 3         private readonly IDatabase _redis;
 4         private readonly IDatabase _redis2;
 5         public HomeController(RedisHelp redisHelp,RedisHelp_Test redisHelp_Test)
 6         {
 7             _redis = redisHelp.GetDatabase();
 8             _redis2 = redisHelp_Test.GetDatabase();
 9         }
10         public IActionResult Index()
11         {
12                 _redis.StringSet("myName", "ypf");
13                 var data = _redis.StringGet("myName");
14                 var data2 = _redis2.StringGet("myName");
15                  return View();
16         }
17     }
HomeController

 

三. 后續目錄

          第一節: String類型和Hash類型的介紹和案例應用

          第二節: Set類型和SortedSet類型的介紹和案例應用

          第三節: List類型的介紹、生產者消費者模式、發布訂閱模式

          第四節:Geo類型介紹以及Redis批量操作、事務、分布式鎖

          第五節:Redis架構演變歷程和cluster集群模式架構的搭建

          第六節:秒殺業務/超賣問題的幾種解決思路

          第七節:

          第八節:

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 本人才疏學淺,用郭德綱的話說“我是一個小學生”,如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM