1. 程式人生 > >C# Redis

C# Redis

反向 CA aps 類型比較 tps 關閉 .com 硬盤 頭部

概念

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

  Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹復制。存盤可以有意無意的對數據進行寫操作。

Redis 與 Memcached 區別

  • Memcached是多線程,而Redis使用單線程。(個人認為Memcached在讀寫處理速度上由於Redis)
  • Memcached使用預分配的內存池的方式,Redis使用現場申請內存的方式來存儲數據,並且可以配置虛擬內存。
  • Redis可以實現持久化(也就是說redis需要經常將內存中的數據同步到硬盤中來保證持久化),主從復制,實現故障恢復。
  • Memcached只是簡單的key與value,但是Redis支持數據類型比較多。包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。

Redis支持兩種持久化方式:

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

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

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

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

Windows安裝Redis

以cmd安裝方法

1.下載安裝包:https://github.com/dmajkic/redis/downloads

2.安裝包下載後根據操作系統選擇對應版本文件,裏面會有幾個dll分別為:

redis-server.exe:服務程序
redis-check-dump.exe:本地數據庫檢查
redis-check-aof.exe:更新日誌檢查
redis-benchmark.exe:性能測試,用以模擬同時由N個客戶端發送M個 SETs/GETs 查詢.
redis-cli.exe: 服務端開啟後,我們的客戶端就可以輸入各種命令測試了

首先以管理員身份打開cmd (窗口+R),進入到安裝包下載的位置。輸入:redis-server.exe redis.conf 開啟Redis服務。提示信息沒有報錯表示啟動成功。

技術分享圖片

此窗口要保持開啟狀態,如果關閉Redis服務也會相即被關閉。使用客戶端測試一下數據。

技術分享圖片

現在來觀察Redis是怎麽持久化存儲數據到硬盤上。(快照是默認的持久化方式,默認的文件名稱為dump.rdb)

技術分享圖片

可以看到Redis服務端在一段時間後將數據庫保存在磁盤上,文件為:dump.rdb。

以weindows服務安裝Redis方法:

下載Redis服務安裝包:https://github.com/rgl/redis/downloads

下載完成後直接點擊.exe下一步下一步OK。安裝完後我們會在windows服務中找到Redis Service服務。註意啟動服務後在進行相關測試。

技術分享圖片

代碼實例

在調用Redis服務前需要準備三個DLL。下載地址:【Redis調用驅動】在項目中引用即可。

使用Redis中存儲常用的5種數據類型:String,Hash,List,SetSorted set編寫實例代碼

技術分享圖片 技術分享圖片
static void Main(string[] args)
{
    //在Redis中存儲常用的5種數據類型:String,Hash,List,SetSorted set

    RedisClient client = new RedisClient("172.21.0.192", 6379);
    client.FlushAll();

    #region string
    client.Add<string>("StringValueTime", "我已設置過期時間噢30秒後會消失", DateTime.Now.AddMilliseconds(30000));
    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內部的很多實現,包括發送緩沖隊列等也都是用的這個數據結構 
     */
    client.EnqueueItemOnList("QueueListId", "1.張三");  //入隊
    client.EnqueueItemOnList("QueueListId", "2.張四");
    client.EnqueueItemOnList("QueueListId", "3.王五");
    client.EnqueueItemOnList("QueueListId", "4.王麻子");
    int q = client.GetListCount("QueueListId");
    for (int i = 0; i < q; i++)
    {
        Console.WriteLine("QueueListId出隊值:{0}", client.DequeueItemFromList("QueueListId"));   //出隊(隊列先進先出)
    }

    client.PushItemToList("StackListId", "1.張三");  //入棧
    client.PushItemToList("StackListId", "2.張四");
    client.PushItemToList("StackListId", "3.王五");
    client.PushItemToList("StackListId", "4.王麻子");
    int p = client.GetListCount("StackListId");
    for (int i = 0; i < p; i++)
    {
        Console.WriteLine("StackListId出棧值:{0}", client.PopItemFromList("StackListId"));   //出棧(棧先進後出)
    }


    #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
}
技術分享圖片

輸出結果:

技術分享圖片

總結

  Redis的存儲容災性比較完善,所支持的存儲數據類型比較全。比較坑的是版本2.X之下都不支持服務器集群,只能單機。在Redis 3.0中服務器集群功能才亮相。 操作起來總體感覺比較簡單容易上手。

http://www.cnblogs.com/caokai520/p/4409712.html

C# Redis