.Net Core使用分散式快取Redis:基礎
一、前言
Redis的介紹網上很多不再贅述。本次環境為net core 2.2,使用的StackExchange.Redis來操作Redis。
二、引用Microsoft.Extensions.Caching.StackExchangeRedis
通過nuget搜尋Microsoft.Extensions.Caching.StackExchangeRedis安裝,因為依賴項版本的問題我這裡用的版本是2.2.5,其本質上也是封裝的StackExchange.Redis,但是它實現了net core規定的IDistributedCache介面。
三、新增redis服務
在Startup.cs中的ConfigureServices中新增Redis的服務,會自動進行依賴注入。最簡單的如下:
public void ConfigureServices(IServiceCollection services) {//...... //新增redis連線 services.AddStackExchangeRedisCache(options => { options.Configuration = "127.0.0.1:6379"; options.InstanceName = "SampleInstance"; }); //...... }
InstaceName:例項名,加在redis的key前面的。
Configuration:連線redis的連結。
還存在一個優先順序更高的ConfigurationOptions,可以配置多個redis服務的連線、密碼等。
public void ConfigureServices(IServiceCollection services) {//..... //新增redis連線 services.AddStackExchangeRedisCache(options => { options.ConfigurationOptions = new ConfigurationOptions() { EndPoints = { { "127.0.0.1", 6379 } }, //Password = "123456" }; }); //...... }
具體的屬性如下:
配置選項 | 預設 | 含義 |
---|---|---|
AbortOnConnectFail |
true (false 在Azure上) |
如果為true,Connect 則在沒有伺服器可用時將不會建立連線 |
AllowAdmin |
false |
啟用一系列被認為具有風險的命令 |
ChannelPrefix |
null |
所有釋出/訂閱操作的可選通道字首 |
ConnectRetry |
3 |
初始期間重複嘗試連線的次數 Connect |
ConnectTimeout |
5000 |
連線操作超時(毫秒) |
ConfigurationChannel |
__Booksleeve_MasterChanged |
用於傳達配置更改的廣播頻道名稱 |
ConfigCheckSeconds |
60 |
檢查配置的時間(秒)。如果支援,它可以充當互動式套接字的保持活動狀態。 |
DefaultDatabase |
null |
預設資料庫索引,從0 到databases - 1 |
KeepAlive |
-1 |
傳送訊息以幫助套接字保持活動的時間(秒)(預設為60秒) |
ClientName |
null |
標識Redis中的連線 |
Password |
null |
Redis伺服器密碼 |
Proxy |
Proxy.None |
使用中的代理型別(如果有);例如“ twemproxy” |
ResolveDns |
false |
指定DNS解析應該是明確且渴望的,而不是隱式的 |
ResponseTimeout |
SyncTimeout |
決定套接字是否不健康的時間(毫秒) |
Ssl |
false |
指定應使用SSL加密 |
SslHost |
null |
在伺服器的證書上強制使用特定的SSL主機身份 |
SslProtocols |
null |
使用加密連線時支援Ssl / Tls版本。使用“ |” 提供多個值。 |
SyncTimeout |
5000 |
允許同步操作的時間(毫秒) |
TieBreaker |
__Booksleeve_TieBreak |
在模稜兩可的主方案中用於選擇伺服器的金鑰 |
DefaultVersion |
(3.0 在Azure中,否則2.0 ) |
Redis版本級別(在伺服器不可用時有用) |
WriteBuffer |
4096 |
輸出緩衝區的大小 |
四、操作Redis
在控制器中通過建構函式依賴注入獲取redis連線物件。
public class HomeController : Controller { private readonly IDistributedCache cache; public HomeController(IDistributedCache _cache) { this.cache = _cache; } }
由於是實現了IDistributedCache規定的介面Get、Set、Remove、Refresh等。
所以設定快取(有則更新,無則新增)、獲取快取、重新整理快取(不是重新整理值是重新整理過期時間)和刪除快取的程式碼如下。
//編輯快取 cache.SetString(key, value); //獲取快取 var values = cache.GetString(key); //更新快取過期時間 cache.RefreshAsync(key); //刪除快取 cache.RemoveAsync(key);
如果想設定快取過期時間則通過DistributedCacheEntryOptions,它可以設定滑動過期時間(SlidingExpiration)、絕對過期時間(AbsoluteExpiration)和相對於現在的絕對過期時間(AbsoluteExpirationRelativeToNow)。
var options = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(20)); cache.SetString(key, value, options);
通過redis的視覺化工具Redis Desktop Manager可以看到快取儲存在一號庫為hash型別,有我們儲存的值、滑動過期時間和絕對過期時間。不過獲取到的資料為string。
五、使用StackExchange.Redis
上面的程式碼存在一個問題,就是IDistributedCache之後對快取的儲存預設為其規定格式的hash型別,雖然我們獲取到的資料為string。這樣我們想操作list、set等其他型別就不行了,並且不能指定庫進行儲存。所以為了更加靈活這時候就要直接用StackExchange.Redis。
因為引用Microsoft.Extensions.Caching.StackExchangeRedis的時候已經帶上了StackExchange.Redis.dll的依賴項,所以不用再引用了,否則在nuget中搜索StackExchange.Redis進行引用。
1.基本使用
StackExchange.Redis 中核心物件是在 StackExchange.Redis 名稱空間中的 ConnectionMultiplexer 類,這個物件隱藏了多個伺服器的詳細資訊。 因為 ConnectionMultiplexer 要做很多事,所以它被設計為在呼叫者之間可以共享和重用,不需要在執行每一個操作的時候就建立一個 ConnectionMultiplexer ,它完全是執行緒安全的。 但現在,讓我們來先建立一個ConnectionMultiplexer 類的例項儲存以重用。 使用 ConnectionMultiplexer.Connect 或 ConnectionMultiplexer.ConnectAsync方法,傳遞配置字串或ConfigurationOptions 物件(同上面提到過的)。 配置字串可以採用逗號分隔的一系列節點的形式訪問多個服務,所以讓我們在預設埠(6379)上連線到本地機器上的一個例項:
private static ConnectionMultiplexer redisConnection { get; } static RedisCache() { redisConnection = ConnectionMultiplexer.Connect("127.0.0.1:6379"); }
ConnectionMultiplexer實現了IDisposable介面而且可以在不再需要的時候處理釋放掉。
2.使用Redis
訪問Redis使用上述獲取的連線物件:
IDatabase db = redisConnection.GetDatabase(0);
用GetDatabase()返回的物件成本很低,不需要特殊儲存。可以傳入redis資料庫的號碼,使用指定資料庫,上面的例子就是使用0號資料庫。
擁有了IDatabase就可以呼叫方法去操作redis,所有的方法都有同步和非同步兩套,命名和微軟要求的一樣。
下面簡單的對五種資料型別進行基礎操作:
(1)String字串
新增
await redisConnection.GetDatabase().StringSetAsync(key, value, TimeSpan.FromSeconds(20));
獲取
await redisConnection.GetDatabase().StringGetAsync(key);
(2)List列表
從列表底部和頂部插入
//底部插入 await redisConnection.GetDatabase().ListRightPushAsync(key, value); //頂部插入 await redisConnection.GetDatabase().ListLeftPushAsync(key, value);
從列表底部和頂部獲取一個數據
//底部獲取一個 await redisConnection.GetDatabase().ListRightPopAsync(key); //頂部獲取一個 await redisConnection.GetDatabase().ListLeftPopAsync(key);
(3)Hash雜湊
新增
await redisConnection.GetDatabase().HashSetAsync(key, primaryKey, value1); await redisConnection.GetDatabase().HashSetAsync(key, primaryKey, value2);
獲取
await redisConnection.GetDatabase().HashGetAsync(key, primaryKey);
(4)Set集合
新增
await redisConnection.GetDatabase().SetAddAsync(key, value);
獲取並集
await redisConnection.GetDatabase().SetCombine(SetOperation.Union, key1, key2);
(5)Sorted Set有序集合
新增
await redisConnection.GetDatabase().SortedSetAdd(key, value, sort);
&n