文章出處

回到目錄

兩雄爭霸

使用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的實例,并沒有出現阻塞的情況,即同一個鏈路,處理了多個任務!

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()