Lind.DDD.RedisClient~對StackExchange.Redis呼叫者的封裝及多路複用技術
阿新 • • 發佈:2018-12-30
兩雄爭霸
使用StackExchange.Redis的原因是因為它開源,免費,而對於商業化的ServiceStack.Redis
,它將一步步被前者取代,開源將是一種趨勢,商業化也值得被我們尊重,畢竟人家研究程式碼也不容易,做商品也很正常,當然這不是我們今天的重點,今天主要說一下對StackExchange.Redis的封裝,它與ServicesStack.redis最大的不同就是,它沒有執行緒池的概念,這對於初學者絕對是個坑,大家使用時一定要註冊,StackExchange.redis的物件一定要做成靜態化的,或者單例的,不然,你的伺服器的CPU將在不久的將來出現瓶頸,可以設想一下,網路socket只建立連線,而不被釋放,是個什麼味道!
(平凡建立連線,用完釋放,也是一種資料的浪費)
一家獨佔-多路複用
資料通訊系統或計算機網路系統中,傳輸媒體的頻寬或容量往往會大於傳輸單一訊號的需求,為了有效地利用通訊線路,希望一個通道同時傳輸多路訊號,這就是所謂的多路複用技術(Multiplexing)。採用多路複用技術能把多個訊號組合起來在一條物理通道上進行傳輸,在遠距離傳輸時可大大節省電纜的安裝和維護費用。
大叔定義:簡單的說,就是一個連線,一個鏈路,供多個執行緒使用,發資料包,收資料包等!
Lind.DDD.RedisClient就簡單了
/// <summary> /// StackExchange.Redis管理者/// 注意:這個客戶端沒有連線池的概念,而是有了多路複用技術 /// </summary> public class RedisManager { /// <summary> /// 鎖物件 /// </summary> private static object _locker = new object(); /// <summary> /// StackExchange.Redis物件 /// </summary> privatestatic ConnectionMultiplexer instance; /// <summary> /// 得到StackExchange.Redis單例物件 /// </summary> public static ConnectionMultiplexer Instance { get { if (instance == null) { lock (_locker) { if (instance != null) return instance; instance = GetManager(); return instance; } } return instance; } } /// <summary> /// 構建連結,返回物件 /// </summary> /// <param name="connectionString"></param> /// <returns></returns> private static ConnectionMultiplexer GetManager() { string connectionString = ConfigConstants.ConfigManager.Config.Redis.Host; if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentNullException("請配置Redis連線串!"); } return ConnectionMultiplexer.Connect(connectionString); } }
對於多路利用的併發測試
[TestMethod] public void Redis_Async() { List<Action> actionList = new List<Action>(); actionList.Add(() => { for (int i = 0; i < 100; i++) { RedisClient.RedisManager.Instance.GetDatabase().SetAdd("test01", i.ToString()); Thread.Sleep(100); Console.WriteLine("test011" + i); } }); actionList.Add(() => { for (int i = 0; i < 100; i++) { RedisClient.RedisManager.Instance.GetDatabase().SetAdd("test02", i.ToString()); Thread.Sleep(10); Console.WriteLine("test012" + i); } }); Parallel.Invoke(actionList.ToArray()); }
通過測試和觀察,我們可以看到,這個併發的執行緒同時使用一個RedisManager的例項,並沒有出現阻塞的情況,即同一個鏈路,處理了多個任務!