基本用法
ConnectionMultiplexer 類是StackExchange.Redis的中樞對象,它在StackExchange.Redis名稱空間中;
這個對象封裝了很多基礎服務物件的詳細資料。由於 ConnectionMultiplexer 做了很多底層處理,它在調用者之間被設計為共用和重用。你不應該為每一個操作都建立一個 ConnectionMultiplexer 對象。該對象是完全安全執行緒的。在隨後所有的樣本中,ConnectionMultiplexer 被假定成一個儲存起來且可供重用的對象。
現在,讓我們來建立一個。我們可以使用 ConnectionMultiplexer.Connect 或者 ConnectionMultiplexer.ConnectAsync 並且傳遞一個配置字串或者 ConfigurationOptions 對象來完成建立。配置字串可以被逗號分隔成一系列的節點形式,讓我們在本地機器上使用預設連接埠 6379 來串連到一個執行個體。
using StackExchange.Redis;...ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");// ^^^ 儲存並重用該對象
注意:ConnectionMultiplexer 實現了 IDisposable 介面,當不在需要的時候,我們可以釋放它。但是,我故意不顯示的使用 using 語句。由於該對象是一個很耗費資源的對象,因此最好是重用該對象。
一個更複雜的情境可能涉及到主/從服務的設定。對於這種用法,只需要簡單的設定一個連接字串,該字串包含主從伺服器。(它能夠自動的識別出主伺服器)
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379");
如果發現兩個節點都是主節點(主伺服器),它能夠通過打破平衡(權衡決策)指定那個是主伺服器,從而解決這個問題。但是這種情況是非常罕見的。
如果你有了一個 ConnectionMultiplexer 對象,那麼有3個事情是你可能想要做的: 訪問redis資料庫(注意:在叢集情況下,一個單一的邏輯資料庫可能分布在多個節點當中) 使用redis的發布/訂閱功能 以維護和監控為目的,訪問一個獨立的伺服器 使用redis資料庫
訪問redis資料庫就是這樣簡單:
IDatabase db = redis.GetDatabase();
GetDatabase 方法返回的對象是一個廉價的直通對象,並不需要儲存。注意redis支援多資料庫(儘管這不是支援叢集);在調用 GetDatabase 時可以任意的指定調用的是那個資料庫。還有,如果你計劃使用非同步API,那你需要為 Task.AsyncState 指定一個值,也可以這樣指定:
int databaseNumber = ...object asyncState = ...IDatabase db = redis.GetDatabase(databaseNumber, asyncState);
一旦你擁有 IDatabase 對象,那麼我們就可以簡單的調用Redis API。注意所有的方法都有同步和非同步實現。這符合微軟的命名規範,非同步方法呼叫全部以 Async結尾,並且全部都是可等待的。
最簡單的操作是儲存並且取回一個值:
string value = "abcdefg";db.StringSet("mykey", value);...string value = db.StringGet("mykey");Console.WriteLine(value); // writes: "abcdefg"
注意:String首碼表示的是Redis的String類型,並且它與.Net的Sting類型在很大程度上是不同的。儘管這兩者都能儲存文本資料。
然而,redis允許Key和Value都為原生的位元組資料。樣本如下:
byte[] key = ..., value = ...;db.StringSet(key, value);...byte[] value = db.StringGet(key);
Redis資料庫命令所覆蓋的Redis資料類型都是可用的。 使用Redis發布/訂閱功能
Redis另一個常用的功能是作為發布/訂閱訊息的分發工具;這也是很簡單的,
在串連失敗時,ConnectionMultiplexer 將會處理所有的重訂閱細節。
ISubscriber sub = redis.GetSubscriber();
GetSubscriber 返回了一個不需要儲存的廉價對象。 發布/訂閱API沒有資料庫的概念,但正如之前所提到的,我們可以提供一個非同步狀態(async-state)。注意:所有的訂閱都是全域的。它們不局限於 ISubscriber 的生命週期。發布訂閱功能在Redis中叫做通道”channels”;通道不需要預先定義在伺服器上(一個令人關注的使用是每個使用者的通知通道,例如:Stack Overflow 即時驅動更新部分)。這在.NET中是很常見的,訂閱採用匿名函數回調的方式來處理髮布訊息:
sub.Subscribe("messages", (channel, message) => { Console.WriteLine((string)message);});
你可以單獨的發布一個訊息到通道中:
sub.Publish("messages", "hello");
這會將”hello”(即時的)發布到訂閱了該訊息的控制台中。正如前面所提到的,通道名稱和訊息都可以使用位元組類型。
在順序性和訊息並發處理方面,請參考發布/訂閱 訊息順序 訪問獨立的伺服器
出於維護為目的,有時候需要發出特定於某個伺服器的命令:
IServer server = redis.GetServer("localhost", 6379);
GetServer 方法將會接受一個 EndPoint 對象或伺服器端有唯一標識的索引值對對象。和之前一樣,GetServer 方法返回一個不需要儲存的廉價對象。並且非同步狀態(async-state)是可被選擇指定的。注意:可用的終結點的集合也是可用的:
EndPoint[] endpoints = redis.GetEndPoints();
來自 IServer 的伺服器端命令都是可用的;例如:
DateTime lastSave = server.LastSave();ClientInfo[] clients = server.ClientList();
同步 VS 非同步 VS 即發即棄
在StackExchange.Redis中,有3個主要的使用機制:
同步 - 在操作完成之前方法會返回給調用者(注意:儘管這可能會阻塞調用者,但是決不會阻塞其他線程;StackExchange.Redis的關鍵理念就是它積極共用並發調用方之間的串連)
非同步 - 操作將在未來的某個時間完成,並且以 Task 或者 Task\
string value = "abcdefg";await db.StringSetAsync("mykey", value);...string value = await db.StringGetAsync("mykey");Console.WriteLine(value); // writes: "abcdefg"
在所有的方法中,使用即發即棄訪問是通過選擇性參數 CommandFlags flags (預設是傳入該參數)來實現的。這樣使用時,方法會立即返回預設值(因此通常返回一個字串的方法會一直返回 null,而返回一個 Int64 方法會一直返回0)。該操作將會在後台繼續執行。一個典型的用例是頁面點擊率統計:
db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget);