国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

基于C#的MongoDB數據庫開發(fā)應用(4)--Redis的安裝及使用

2019-11-14 13:33:19
字體:
來源:轉載
供稿:網友

在前面介紹了三篇關于MongoDB數據庫的開發(fā)使用文章,嚴格來講這個不能歸類于MongoDB數據庫開發(fā),不過Redis又有著和MongoDB數據庫非常密切的關系,它們兩者很接近,Redis主要是內存中的NoSQL數據庫,用來提高性能的;MongoDB數據庫則是文件中的NoSQL數據庫,做數據序列號存儲使用的,它們兩者關系密切又有所區(qū)別。本篇主要介紹Redis的安裝及使用,為后面Redis和MongoDB數據庫的聯(lián)合使用先鋪下基礎。

1、Redis基礎及安裝

Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value數據庫,和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區(qū)別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了master-slave(主從)同步。

Redis的代碼遵循ANSI-C編寫,可以在所有POSIX系統(tǒng)(如linux*BSD, Mac OS X, Solaris等)上安裝運行。而且Redis并不依賴任何非標準庫,也沒有編譯參數必需添加。

1)Redis支持兩種持久化方式:

   (1):snapshotting(快照)也是默認方式.(把數據做一個備份,將數據存儲到文件)

   (2)Append-only file(縮寫aof)的方式 

   快照是默認的持久化方式,這種方式是將內存中數據以快照的方式寫到二進制文件中,默認的文件名稱為dump.rdb.可以通過配置設置自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key鍵修改就自動做快照.

   aof方式:由于快照方式是在一定間隔時間做一次的,所以如果Redis意外down掉的話,就會丟失最后一次快照后的所有修改。aof比快照方式有更好的持久化性,是由于在使用aof時,redis會將每一個收到的寫命令都通過write函數追加到文件中,當redis重啟時會通過重新執(zhí)行文件中保存的寫命令來在內存中重建整個數據庫的內容。 

2)Redis數據結構

Redis 的作者antirez曾稱其為一個數據結構服務器(data structures server),這是一個非常準確的表述,Redis的所有功能就是將數據以其固有的幾種結構保存,并提供給用戶操作這幾種結構的接口。我們可以想象我們在各種語言中的那些固有數據類型及其操作。

Redis目前提供四種數據類型:string,list,setzset(sorted set)和Hash

  • string是最簡單的類型,你可以理解成與Memcached一模一個的類型,一個key對應一個value,其上支持的操作與Memcached的操作類似。但它的功能更豐富。
  • list是一個鏈表結構,主要功能是push、pop、獲取一個范圍的所有值等等。操作中key理解為鏈表的名字。
  • set是集合,和我們數學中的集合概念相似,對集合的操作有添加刪除元素,有對多個集合求交并差等操作。操作中key理解為集合的名字。
  • zset是set的一個升級版本,他在set的基礎上增加了一個順序屬性,這一屬性在添加修改元素的時候可以指定,每次指定后,zset會自動重新按新的值調整順序。可以理解了有兩列的MySQL表,一列存value,一列存順序。操作中key理解為zset的名字。
  • Hash數據類型允許用戶用Redis存儲對象類型,Hash數據類型的一個重要優(yōu)點是,當你存儲的數據對象只有很少幾個key值時,數據存儲的內存消耗會很小.更多關于Hash數據類型的說明請見: http://code.google.com/p/redis/wiki/Hashes

3)Redis數據存儲

Redis的存儲分為內存存儲、磁盤存儲和log文件三部分,配置文件中有三個參數對其進行配置。

save seconds updatessave配置,指出在多長時間內,有多少次更新操作,就將數據同步到數據文件。這個可以多個條件配合,比如默認配置文件中的設置,就設置了三個條件。

appendonly yes/no appendonly配置,指出是否在每次更新操作后進行日志記錄,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為redis本身同步數據文件是按上面的save條件來同步的,所以有的數據會在一段時間內只存在于內存中。

appendfsync no/always/everysec appendfsync配置,no表示等操作系統(tǒng)進行數據緩存同步到磁盤,always表示每次更新操作后手動調用fsync()將數據寫到磁盤,everysec表示每秒同步一次。

 

4)Redis的安裝

Redis可以在不同的平臺運行,不過我主要基于Windows進行開發(fā)工作,所以下面主要是基于Windows平臺進行介紹。

Redis可以安裝以DOS窗口啟動的,也可以安裝為Windows服務的,一般為了方便,我們更愿意把它安裝為Windows服務,這樣可以比較方便管理。下載地址:https://github.com/MSOpenTech/redis/releases下載,安裝為Windows服務即可。

當前可以下載到最新的Windows安裝版本為3.0,安裝后作為Windows服務運行,安裝后可以在系統(tǒng)的服務里面看到Redis的服務在運行了,如下圖所示。

安裝好Redis后,還有一個Redis伴侶Redis Desktop Manager需要安裝,這樣可以實時查看Redis緩存里面有哪些數據,具體地址如下:http://redisdesktop.com/download

下載屬于自己平臺的版本即可

下載安裝后,打開運行界面,如果我們往里面添加鍵值的數據,那么可以看到里面的數據了。

 

2、Redis的C#使用

Redis目前提供四種數據類型:string,list,setzset(sorted set)和Hash。因此它在C#里面也有對應的封裝處理,而且有很多人對他進行了封裝,提供了很多的響應開發(fā)包,具體可以訪問http://redis.io/clients#c 進行了解。一般建議用ServiceStack.Redis的封裝驅動比較好,具體的使用可以參考https://github.com/ServiceStack/ServiceStack.Redis。

我們開發(fā)C#代碼的時候,可以在NuGet程序包上面進行添加對應的ServiceStack.Redis引用,如下所示。

 

在彈出的NuGet程序包里面,輸入ServiceStack.Redis進行搜索,并添加下面的驅動引用即可。

這樣會在項目引用里面添加了幾個對應的程序集,如下所示。

在C#里面使用Redis,首先需要實例化一個Redis的客戶端類,如下所示。

        //創(chuàng)建一個Redis的客戶端類        RedisClient client = new RedisClient("127.0.0.1", 6379);

在使用前,我們需要清空所有的鍵值存儲,使用FushAll方法即可,如下所示

            //Redis FlushAll 命令用于清空整個 Redis 服務器的數據(刪除所有數據庫的所有 key )。             client.FlushAll();

根據上面的驅動,可以為不同類型的處理編寫一些演示代碼,下面代碼是摘錄網上的案例進行介紹。

            #region string類型的測試代碼            client.Add<string>("StringValueTime", "帶有有效期的字符串", DateTime.Now.AddMilliseconds(10000));            while (true)            {                if (client.ContainsKey("StringValueTime"))                {                    Console.WriteLine("String.鍵:StringValue, 值:{0} {1}", client.Get<string>("StringValueTime"), DateTime.Now);                    Thread.Sleep(10000);                }                else                {                    Console.WriteLine("鍵:StringValue, 值:已過期 {0}", DateTime.Now);                    break;                }            }            client.Add<string>("StringValue", " String和Memcached操作方法差不多");            Console.WriteLine("數據類型為:String.鍵:StringValue, 值:{0}", client.Get<string>("StringValue"));            Student stud = new Student() { id = "1001", name = "李四" };            client.Add<Student>("StringEntity", stud);            Student Get_stud = client.Get<Student>("StringEntity");            Console.WriteLine("數據類型為:String.鍵:StringEntity, 值:{0} {1}", Get_stud.id, Get_stud.name);            #endregion            #region Hash類型的測試代碼            client.SetEntryInHash("HashID", "Name", "張三");            client.SetEntryInHash("HashID", "Age", "24");            client.SetEntryInHash("HashID", "Sex", "");            client.SetEntryInHash("HashID", "Address", "上海市XX號XX室");            List<string> HaskKey = client.GetHashKeys("HashID");            foreach (string key in HaskKey)            {                Console.WriteLine("HashID--Key:{0}", key);            }            List<string> HaskValue = client.GetHashValues("HashID");            foreach (string value in HaskValue)            {                Console.WriteLine("HashID--Value:{0}", value);            }            List<string> AllKey = client.GetAllKeys(); //獲取所有的key。            foreach (string Key in AllKey)            {                Console.WriteLine("AllKey--Key:{0}", Key);            }            #endregion            #region List類型的測試代碼            /*             * list是一個鏈表結構,主要功能是push,pop,獲取一個范圍的所有的值等,操作中key理解為鏈表名字。              * Redis的list類型其實就是一個每個子元素都是string類型的雙向鏈表。我們可以通過push,pop操作從鏈表的頭部或者尾部添加刪除元素,             * 這樣list既可以作為棧,又可以作為隊列。Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,             * Redis內部的很多實現,包括發(fā)送緩沖隊列等也都是用的這個數據結構              */            client.EnqueueItemOnList("QueueListId", "1.張三");  //入隊            client.EnqueueItemOnList("QueueListId", "2.張四");            client.EnqueueItemOnList("QueueListId", "3.王五");            client.EnqueueItemOnList("QueueListId", "4.王麻子");            long q = client.GetListCount("QueueListId");            Console.WriteLine(client.GetItemFromList("QueueListId", 0));            for (int i = 0; i < q; i++)            {                Console.WriteLine("QueueListId出隊值:{0}", client.DequeueItemFromList("QueueListId"));   //出隊(隊列先進先出)            }            q = client.GetListCount("QueueListId");            Console.WriteLine(q);            client.PushItemToList("StackListId", "1.張三");  //入棧            client.PushItemToList("StackListId", "2.張四");            client.PushItemToList("StackListId", "3.王五");            client.PushItemToList("StackListId", "4.王麻子");            long p = client.GetListCount("StackListId");            for (int i = 0; i < p; i++)            {                Console.WriteLine("StackListId出棧值:{0}", client.PopItemFromList("StackListId"));   //出棧(棧先進后出)            }            q = client.GetListCount("StackListId");            Console.WriteLine(q);            #endregion            #region Set無序集合的測試代碼            /*             它是string類型的無序集合。set是通過hash table實現的,添加,刪除和查找,對集合我們可以取并集,交集,差集             */            client.AddItemToSet("Set1001", "小A");            client.AddItemToSet("Set1001", "小B");            client.AddItemToSet("Set1001", "小C");            client.AddItemToSet("Set1001", "小D");            HashSet<string> hastsetA = client.GetAllItemsFromSet("Set1001");            foreach (string item in hastsetA)            {                Console.WriteLine("Set無序集合ValueA:{0}", item); //出來的結果是無須的            }            client.AddItemToSet("Set1002", "小K");            client.AddItemToSet("Set1002", "小C");            client.AddItemToSet("Set1002", "小A");            client.AddItemToSet("Set1002", "小J");            HashSet<string> hastsetB = client.GetAllItemsFromSet("Set1002");            foreach (string item in hastsetB)            {                Console.WriteLine("Set無序集合ValueB:{0}", item); //出來的結果是無須的            }            HashSet<string> hashUnion = client.GetUnionFromSets(new string[] { "Set1001", "Set1002" });            foreach (string item in hashUnion)            {                Console.WriteLine("求Set1001和Set1002的并集:{0}", item); //并集            }            HashSet<string> hashG = client.GetIntersectFromSets(new string[] { "Set1001", "Set1002" });            foreach (string item in hashG)            {                Console.WriteLine("求Set1001和Set1002的交集:{0}", item);  //交集            }            HashSet<string> hashD = client.GetDifferencesFromSet("Set1001", new string[] { "Set1002" });  //[返回存在于第一個集合,但是不存在于其他集合的數據。差集]            foreach (string item in hashD)            {                Console.WriteLine("求Set1001和Set1002的差集:{0}", item);  //差集            }            #endregion            #region  SetSorted 有序集合的測試代碼            /*             sorted set 是set的一個升級版本,它在set的基礎上增加了一個順序的屬性,這一屬性在添加修改.元素的時候可以指定,             * 每次指定后,zset(表示有序集合)會自動重新按新的值調整順序。可以理解為有列的表,一列存 value,一列存順序。操作中key理解為zset的名字.             */            client.AddItemToSortedSet("SetSorted1001", "1.劉仔");            client.AddItemToSortedSet("SetSorted1001", "2.星仔");            client.AddItemToSortedSet("SetSorted1001", "3.豬仔");            List<string> listSetSorted = client.GetAllItemsFromSortedSet("SetSorted1001");            foreach (string item in listSetSorted)            {                Console.WriteLine("SetSorted有序集合{0}", item);            }            #endregion

對于具體類型的類對象,也可以使用As方法進行轉換為對應的處理對象進行處理,如下所示

IRedisTypedClient<Phone> phones = client.As<Phone>();

具體的測試代碼如下所示。

        /// <summary>        /// Redis對對象類的處理例子        /// </summary>        PRivate void btnTypeValue_Click(object sender, EventArgs e)        {            IRedisTypedClient<Phone> phones = client.As<Phone>();            Phone phoneFive = phones.GetValue("5");            if (phoneFive == null)            {                Thread.Sleep(50);                phoneFive = new Phone                {                    Id = 5,                    Manufacturer = "Apple",                    Model = "xxxxx",                    Owner = new Person                    {                        Id = 1,                        Age = 100,                        Name = "伍華聰",                        Profession = "計算機",                        Surname = "wuhuacong"                    }                };                phones.SetEntry(phoneFive.Id.ToString(), phoneFive);            }            client.Store<Phone>(                new Phone                {                    Id = 2,                    Manufacturer = "LG",                    Model = "test-xxx",                    Owner = new Person                    {                        Id = 2,                        Age = 40,                        Name = "test",                        Profession = "teacher",                        Surname = "wuhuacong"                    }                });            var message = "Phone model is " + phoneFive.Manufacturer + ",";            message += "Phone Owner Name is: " + phoneFive.Owner.Name;            Console.WriteLine(message);        }

以上就是關于Redis的安裝以及簡單的例子使用說明,在具體中,我們可以利用Redis的高性能特性,來構建我們的緩存數據,并且可以利用Redis和MongoDB數據庫的完美銜接,可以整合一起做的更好,為相關的后臺提供更高效的數據處理操作,畢竟在互聯(lián)網的大環(huán)境下,性能是非常重要的。

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 永安市| 达孜县| 临潭县| 乌拉特后旗| 满洲里市| 岳阳市| 正宁县| 龙山县| 治多县| 洛扎县| 岳普湖县| 尖扎县| 博罗县| 漳平市| 南阳市| 托里县| 乌拉特前旗| 商河县| 修武县| 原平市| 邳州市| 丰顺县| 兴化市| 同江市| 新巴尔虎右旗| 乐清市| 陕西省| 得荣县| 南阳市| 拜城县| 竹北市| 南宫市| 宜城市| 马公市| 枣庄市| 成安县| 鞍山市| 开封市| 大兴区| 安溪县| 锡林郭勒盟|