1. 程式人生 > >stackExchange.redis的使用

stackExchange.redis的使用

shell bsp disabled dbr for 方式 shel point org

在StackExchange.Redis中最重要的對象是ConnectionMultiplexer類, 它存在於StackExchange.Redis命名空間中。 這個類隱藏了Redis服務的操作細節,ConnectionMultiplexer類做了很多東西, 在所有調用之間它被設計為共享和重用的。 不應該為每一個操作都創建一個ConnectionMultiplexer 。 ConnectionMultiplexer是線程安全的 , 推薦使用下面的方法。 在所有後續示例中 , 都假定你已經實例化好了一個ConnectionMultiplexer類,它將會一直被重用 , 現在我們來創建一個ConnectionMultiplexer實例。它是通過ConnectionMultiplexer.Connect 或者 ConnectionMultiplexer.ConnectAsync,
傳遞一個連接字符串或者一個ConfigurationOptions 對象來創建的。 連接字符串可以是以逗號分割的多個服務的節點, 我們僅僅需要連接一個在本地計算機中的redis服務,redis服務的默認端口是6379. using StackExchange.Redis; ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");//127.0.0.1 // ^^^ store and re-use this!!! 註意 : ConnectionMultiplexer 實現了IDisposable接口當我們不再需要是可以將其釋放的 , 這裏我故意不使用 using 來釋放他。 簡單來講創建一個ConnectionMultiplexer是十分昂貴的 , 一個好的主意是我們一直重用一個ConnectionMultiplexer對象。
一個復雜的的場景中可能包含有主從復制 , 對於這種情況,只需要指定所有地址在連接字符串中(它將會自動識別出主服務器) ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379"); 假設這裏找到了兩臺主服務器,將會對兩臺服務進行裁決選出一臺作為主服務器來解決這個問題 , 這種情況是非常罕見的 ,我們也應該避免這種情況的發生。 現在你已經擁有了一個 ConnectionMultiplexer , 下面三件事情可能是你想要做的。 1. 訪問數據庫。(註意在使用集群的情況下,一個數據庫可能會分部在多個節點中)
2. 使用redis的發布訂閱功能 3. 維護和監控一臺服務器 訪問數據庫 訪問數據庫的操作非常簡單: IDatabase db = redis.GetDatabase(); GetDatabase 返回一個IDatabase接口。 註意 redis允許配置多個數據庫,可以在調用GetDatabase() 時候指定數據庫.另外,如果你計劃使用異步的api , Task.AsyncState 必須擁有一個值 ,也可以這樣指定。 int databaseNumber = ... object asyncState = ... IDatabase db = redis.GetDatabase(databaseNumber, asyncState); 現在你已經擁有了一個 IDatabase 對象 , 他可以對redis數據庫進行操作。所有的方法都有同步和異步兩個版本 , 按照微軟的命名約定 ,所有的異步方法都以Async結尾。 最簡單的操作 存儲和獲取一個值 。 string value = "abcdefg"; db.StringSet("mykey", value); ... string value = db.StringGet("mykey"); Console.WriteLine(value); // writes: "abcdefg" String前綴這裏代表的是Redis中的String類型 , 和.net中的String類型有很大的區別 , 盡管兩者都可以保存字符串類型。然後 ,Redis允許鍵值為二進制數據 , 示例如下: byte[] key = ..., value = ...; db.StringSet(key, value); ... byte[] value = db.StringGet(key); StackExchange.Redis 支持所有的 redis shell命令, 具體可以參考redis官網。 StackExchange.Redis 使用-發布訂閱 使用Redis的發布訂閱功能 redis另一個常見的用途是發布訂閱功能 。 它非常的簡單 ,當連接失敗時 ConnectionMultiplexer 會自動重新進行訂閱 。 ISubscriber sub = redis.GetSubscriber(); GetSubscriber 方法返回一個 ISubscriber 類型的實例 。發布訂閱功能沒有數據庫的概念,我們可以為其提供一個 async-state 。所有的訂閱都是全局的: ISubscriber 實例不是他們的生命周期 , 發布訂閱的特性在redis中被定義為 “channels” , 渠道不需要預先定義在數據庫中 。 訂閱操作需要一個渠道 名稱和一個回調函數來處理發布的消息。 sub.Subscribe("messages", (channel, message) => { Console.WriteLine((string)message); }); 你可以發布一個消息到指定的渠道中: sub.Publish("messages", "hello"); 他將會將 “hello” 這個消息發布到所有訂閱了messages渠道的客戶端(幾乎是實時的)。 和之前一樣渠道的名稱和消息也可以是二進制的。 指定消息發布的順序(Message Order) 當使用 pub/sub API 時,你可以指定消息是並行還是有序的。 有序的意味著你不需要考慮線程安全的問題 ,同時也意味著消息會通過隊列完全按照你發布的順序來進行傳遞,這必然導致消息的延遲。 並行處理,不能保證消息是按照發布的順序來進行處理的,你的代碼也要保證當存在並發時程序運行正常, 消息的順序通常是無關緊要的, 並行處理可以獲得更好的性能和擴展性。 為確保安全,消息的傳遞默認是有序的。為獲得更好的性能強烈建議你使用並行操作 。 這是非常簡單的。 multiplexer.PreserveAsyncOrder = false; 建議並非是你配置該選項的理由, 是否適合完全取決與你訂閱消息的代碼。 StackExchange.Redis 使用-同步 異步 即發即棄 訪問單個服務器 有時候需要為單個服務器指定特定的命令 。 IServer server = redis.GetServer("localhost", 6379); GetServer方法會接收一個EndPoint類或者一個唯一標識一臺服務器的鍵值對。GetServer 方法返回一個IServer對象。 方法也可以是異步的只需要傳入一個async-state 可以使用如下方法獲取所有可用的終結點: EndPoint[] endpoints = redis.GetEndPoints(); 使用IServer可以使用所有的shell命令,比如: DateTime lastSave = server.LastSave(); ClientInfo[] clients = server.ClientList(); 如果報錯在連接字符串後加 ,allowAdmin=true; 同步 、異步、即發即棄 這是StackExchange.Redis的三種主要使用機制: 同步-在方法返回之前阻塞調用方(雖然會阻塞調用方,但絕不會阻塞其他線程 ,StackExchange.Redis中的關鍵點是共享調用者之間的連接) 異步-在未來的某個時間點操作完成,會立刻返回一個 Task 或者 Task<T> : 之後可以調用 .Wait() 阻塞當前線程,直到處理完成。 ContinueWith 添加一個回調函數 使用 await 這是一個高級特性簡化了操作 即發即棄- 在上面的示例中已經演示同步調用的方法 。 異步調用: string value = "abcdefg"; await db.StringSetAsync("mykey", value); ... string value = await db.StringGetAsync("mykey"); Console.WriteLine(value); // writes: "abcdefg" 即發即棄:通過配置 CommandFlags 來實現即發即棄功能,在該實例中該方法會立即返回,如果是string則返回null 如果是int則返回0.這個操作將會繼續在後臺運行,一個典型的用法頁面計數器的實現: db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget); StackExchange.Redis 使用-配置 Configuration redis有很多不同的方法來配置連接字符串 , StackExchange.Redis 提供了一個豐富的配置模型,當調用Connect 或者 ConnectAsync 時需要傳入。 var conn = ConnectionMultiplexer.Connect(configuration); 這裏的 configuration 參數可以是: 1. 一個 ConfigurationOptions 實例 2. 一個字符串 第二種方式從根本上來說也是ConfigurationOptions。 通過字符串配置連接 最簡單的配置方式只需要一個主機名 var conn = ConnectionMultiplexer.Connect("localhost"); 它將會連接到本地的redis服務器 , 默認6379端口 ,多個連接通過逗號分割 。 其他選項在名稱的後面包含了一個 “= ”。 例如 var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,allowAdmin=true"); 可以將一個字符串轉換為ConfigurationOptions 或者 將一個ConfigurationOptions轉換為字符串 。 ConfigurationOptions options = ConfigurationOptions.Parse(configString); OR string configString = options.ToString(); 推薦的用法是將基礎信息保存在一個字符串中,然後在運行是通過ConfigurationOptions改變其他信息。 string configString = GetRedisConfiguration(); var options = ConfigurationOptions.Parse(configString); options.ClientName = GetAppName(); // only known at runtime options.AllowAdmin = true; conn = ConnectionMultiplexer.Connect(options); 也可以指定密碼 var conn = ConnectionMultiplexer.Connect("contoso5.redis.cache.windows.net,ssl=true,password=..."); 配置選項 ConfigurationOptions 包含大量的配置選項,一些常用的配置如下: abortConnect : 當為true時,當沒有可用的服務器時則不會創建一個連接 allowAdmin : 當為true時 ,可以使用一些被認為危險的命令 channelPrefix:所有pub/sub渠道的前綴 connectRetry :重試連接的次數 connectTimeout:超時時間 configChannel: Broadcast channel name for communicating configuration changes defaultDatabase : 默認0到-1 keepAlive : 保存x秒的活動連接 name:ClientName password:password proxy:代理 比如 twemproxy resolveDns : 指定dns解析 serviceName : Not currently implemented (intended for use with sentinel) ssl={bool} : 使用sll加密 sslHost={string} : 強制服務器使用特定的ssl標識 syncTimeout={int} : 異步超時時間 tiebreaker={string}:Key to use for selecting a server in an ambiguous master scenario version={string} : Redis version level (useful when the server does not make this available) writeBuffer={int} : 輸出緩存區的大小 各配置項用逗號分割 自動和手動配置 在大部分的情況下StackExchange.Redis 會自動的幫我們配置很多選項。 比如 服務器類型,版本, 超時時間 , 主從服務器等.. 盡管如此,有時候我們需要在服務器上面排除一些命令, 這種情況下有必要提供更多信息 ConfigurationOptions config = new ConfigurationOptions { EndPoints = { { "redis0", 6379 }, { "redis1", 6380 } }, CommandMap = CommandMap.Create(new HashSet<string> { // EXCLUDE a few commands "INFO", "CONFIG", "CLUSTER", "PING", "ECHO", "CLIENT" }, available: false), KeepAlive = 180, DefaultVersion = new Version(2, 8, 8), Password = "changeme" }; 也可以使用下面的字符串來設置: redis0:6379,redis1:6380,keepAlive=180,version=2.8.8,$CLIENT=,$CLUSTER=,$CONFIG=,$ECHO=,$INFO=,$PING= 重命名命令 你可以禁用或者重命名一個命令。 按照前面的示例這是通過 CommandMap 來完成的,不過上面使用Create( new HashSet<string> )來進行配置,我們使用Dictionary<string,string>。設置null時代表禁用該命令 var commands = new Dictionary<string,string> { { "info", null }, // disabled { "select", "use" }, // renamed to SQL equivalent for some reason }; var options = new ConfigurationOptions { // ... CommandMap = CommandMap.Create(commands), // ... } 也可以使用下面的字符串來設置: $INFO=,$SELECT=use StackExchange.Redis 使用 - 事件 ConnectionMultiplexer 可以註冊如下事件
  • ConfigurationChanged - 配置更改時
  • ConfigurationChangedBroadcast - 通過發布訂閱更新配置時
  • ConnectionFailed - 連接失敗 , 如果重新連接成功你將不會收到這個通知
  • ConnectionRestored - 重新建立連接之前的錯誤
  • ErrorMessage - 發生錯誤
  • HashSlotMoved - 更改集群
  • InternalError - redis類庫錯誤
分類: Redis http://www.cnblogs.com/skig/p/redis-lua-batch.html

stackExchange.redis的使用