回到目錄 兩雄爭霸 使用StackExchange.Redis的原因是因為它開源,免費,而對於商業化的ServiceStack.Redis,它將一步步被前者取代,開源將是一種趨勢,商業化也值得被我們尊重,畢竟人家研究代碼也不容易,做商品也很正常,當然這不是我們今天的重點,今天主要說一下對StackE ...
兩雄爭霸
使用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> private static 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的實例,並沒有出現阻塞的情況,即同一個鏈路,處理了多個任務!