使用 .NET 與 Azure Cache for Redis 互動
一般而言,用戶端應用程式會使用用戶端程式庫以形成要求,並在 Redis 快取上執行命令。 您可以直接從 Redis 用戶端頁面取得用戶端程式庫清單。
在 Redis 快取上執行命令
StackExchange.Redis 是一個適用於 .NET 語言的熱門高效能 Redis 用戶端。 此套件可以透過 NuGet 取得,而且可以使用命令列或 IDE,新增至您的 .NET 程式碼。 以下是如何使用用戶端的範例。
使用 StackExchange.Redis 連線到您的 Redis 快取
您應該記得我們使用過主機位址、連接埠號碼與存取金鑰來連線到 Redis 伺服器。 Azure 也為一些 Redis 用戶端提供連接字串,這會將此資料包裝成單一字串。 看起來如下所示 (在 cache-name
和 password-here
欄位中會填入實際值):
[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False
您可以將此字串傳遞至 StackExchange.Redis,以建立與伺服器的連線。
請注意,結尾還有兩個參數:
- ssl - 可確保通訊都會加密。
- abortConnection - 即使當時伺服器無法使用,也允許建立連線。
有其他數個選擇性參數 (英文),您可以附加到字串以設定用戶端程式庫。
建立連線
StackExchange.Redis 中的主要連線物件是 StackExchange.Redis.ConnectionMultiplexer
類別。 此物件會精簡連線到 Redis 伺服器 (或伺服器群組) 的程序。 其已最佳化,可有效率地管理連線,而且能夠在您需要存取快取時保持待用。
您使用靜態 ConnectionMultiplexer.Connect
或 ConnectionMultiplexer.ConnectAsync
方法建立 ConnectionMultiplexer
執行個體,傳入連接字串或 ConfigurationOptions
物件。
以下是簡單的範例:
using StackExchange.Redis;
...
var connectionString = "[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False";
var redisConnection = ConnectionMultiplexer.Connect(connectionString);
一旦擁有 ConnectionMultiplexer
,您就可以執行 3 個主要事項:
- 存取 Redis 資料庫。
- 使用此課程模組範圍之外 Redis 的發行者/訂閱者功能。
- 針對維護或監視目的存取個別伺服器。
存取 Redis 資料庫
此 IDatabase
類型代表 Redis 資料庫。 您可以使用 GetDatabase()
方法來擷取資料庫:
IDatabase db = redisConnection.GetDatabase();
提示
透過 GetDatabase
傳回的物件是輕量型物件,而且不需要儲存。 只有 ConnectionMultiplexer
必須保持運作。
一旦您擁有 IDatabase
物件,您可以執行方法來與快取互動。 所有方法都有同步和非同步版本,會傳回 Task
物件,讓其與 async
和 await
關鍵字相容。
以下是在快取中儲存索引鍵/值的範例:
bool wasSet = db.StringSet("favorite:flavor", "i-love-rocky-road");
StringSet
方法會傳回 bool
,指出已設定 (true
) 或未設定 (false
) 值。 然後,我們可以使用 StringGet
方法來擷取值:
string value = db.StringGet("favorite:flavor");
Console.WriteLine(value); // displays: ""i-love-rocky-road""
取得及設定二進位值
您應該記得 Redis 機碼與值是二進位安全。 這些相同的方法可用來儲存二進位資料。 有隱含的轉換運算子可以與 byte[]
類型搭配使用,讓您可以自然地使用資料:
byte[] key = ...;
byte[] value = ...;
db.StringSet(key, value);
byte[] key = ...;
byte[] value = db.StringGet(key);
StackExchange.Redis 表示使用 RedisKey
類型的索引鍵。 這個類別具有 string
與 byte[]
之間隱含的轉換,允許使用文字與二進位機碼,沒有任何複雜度。 值是由 RedisValue
型別表示。 如同使用 RedisKey
,有隱含的轉換,可讓您傳遞 string
或 byte[]
。
其他常見作業
IDatabase
介面包含可以與 Redis 快取搭配使用的其他數種方法。 有方法可以與雜湊、清單、集合和已排序集合搭配使用。
以下是一些可以與單一索引鍵搭配使用的較常見項目,您可以針對介面讀取原始程式碼,以查看完整清單。
方法 | 描述 |
---|---|
CreateBatch |
建立作業群組,以單一單位的形式傳送到伺服器,但不一定會當做一個單位來處理。 |
CreateTransaction |
建立作業群組,以單一單位的形式傳送到伺服器,且作為單一單位在伺服器上進行處理。 |
KeyDelete |
刪除索引鍵/值。 |
KeyExists |
傳回指定索引鍵是否存在於快取中的資訊。 |
KeyExpire |
設定機碼的存留時間 (TTL) 到期日。 |
KeyRename |
重新命名機碼。 |
KeyTimeToLive |
傳回機碼的 TTL。 |
KeyType |
傳回儲存在索引鍵的值類型字串表示法。 傳回的不同類型為:字串、清單、集合、zset 和雜湊。 |
執行其他命令
IDatabase
物件具有 Execute
與 ExecuteAsync
方法,可用來將文字命令傳遞給 Redis 伺服器。 例如:
var result = db.Execute("ping");
Console.WriteLine(result.ToString()); // displays: "PONG"
Execute
與 ExecuteAsync
方法會傳回 RedisResult
物件,這是資料預留位置,其中包含兩個屬性:
Resp2Type
會傳回string
,表示結果類型 -STRING
、INTEGER
等等。IsNull
,當結果為null
時設定要偵測的 true/false 值。
然後,您可以在 RedisResult
上使用 ToString()
,以取得實際傳回值。
您可以使用 Execute
來執行任何支援的命令 - 例如,我們可以取得連線到快取的所有用戶端 ("CLIENT LIST"):
var result = await db.ExecuteAsync("client", "list");
Console.WriteLine($"Type = {result.Resp2Type}\r\nResult = {result}");
這會輸出所有連線的用戶端:
Type = BulkString
Result = id=9469 addr=16.183.122.154:54961 fd=18 name=DESKTOP-AAAAAA age=0 idle=0 flags=N db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=subscribe numops=5
id=9470 addr=16.183.122.155:54967 fd=13 name=DESKTOP-BBBBBB age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=client numops=17
儲存更複雜的值
Redis 以二進位安全字串為核心,但是您可以藉由將物件圖表序列化為文字格式 (通常是 XML 或 JSON),來加以快取。 例如,或許只是針對統計資料用途,我們有 GameStats
物件,如下所示:
public class GameStat
{
public string Id { get; set; }
public string Sport { get; set; }
public DateTimeOffset DatePlayed { get; set; }
public string Game { get; set; }
public IReadOnlyList<string> Teams { get; set; }
public IReadOnlyList<(string team, int score)> Results { get; set; }
public GameStat(string sport, DateTimeOffset datePlayed, string game, string[] teams, IEnumerable<(string team, int score)> results)
{
Id = Guid.NewGuid().ToString();
Sport = sport;
DatePlayed = datePlayed;
Game = game;
Teams = teams.ToList();
Results = results.ToList();
}
public override string ToString()
{
return $"{Sport} {Game} played on {DatePlayed.Date.ToShortDateString()} - " +
$"{String.Join(',', Teams)}\r\n\t" +
$"{String.Join('\t', Results.Select(r => $"{r.team } - {r.score}\r\n"))}";
}
}
我們可以使用 Newtonsoft.Json 程式庫,將此物件的執行個體轉換為字串:
var stat = new GameStat("Soccer", new DateTime(2019, 7, 16), "Local Game",
new[] { "Team 1", "Team 2" },
new[] { ("Team 1", 2), ("Team 2", 1) });
string serializedValue = Newtonsoft.Json.JsonConvert.SerializeObject(stat);
bool added = db.StringSet("event:1950-world-cup", serializedValue);
我們可以加以擷取,並使用反向程序將其轉換回物件:
var result = db.StringGet("event:2019-local-game");
var stat = Newtonsoft.Json.JsonConvert.DeserializeObject<GameStat>(result.ToString());
Console.WriteLine(stat.Sport); // displays "Soccer"
清除連線
當不再需要連線時,您可以 Dispose
ConnectionMultiplexer
。 這樣會關閉所有連線,並且關閉與伺服器的通訊。
redisConnection.Dispose();
redisConnection = null;