C#之Redis所欲爲

一 Redis是一種支持多種數據結構的鍵值對數據庫nginx

1.1Redis下載地址 :https://github.com/MicrosoftArchive/Redisgit

建議下載 .msi結尾的應用程序進行安裝,會自動安裝Redis服務github

Redis默認是不能外網訪問的redis

把Redis部署到本地請忽視下面數據庫

設置防火牆端口例外數組

更改redis.conf 文件服務器

bind 127.0.0.1 protected-mode yes

更改成數據結構

# bind 127.0.0.1 protected-mode no
而後重啓Redis服務,

1.2 Redis支持的數據類型:string、list、set、sortedset、geo(Redis 3.2以上版本),注意不一樣方法寫入的值不能用混了,好比有寫list的方法寫入的值用獲取字符串的方法去獲取就有問題了。併發

1.3 Redis的優勢:異步

支持多種複雜類型的數據結構

高命中的數據是運行在內存中的,數據最終仍是能夠保存到硬盤中,服務器重啓後數據不會丟失

服務器是單線程的,來自全部客戶端的全部命令都是串行執行的,不用擔憂併發修改的問題

支持消息訂閱/通知機制,能夠用做消息隊列

key/value 最大長度容許512M

1.4 Redis的缺點:

Redis是單線程的,所以單個Redis的實例只能使用服務器的一個CPU核,不能充分發揮服務器的性能

 

二 在 .Net中操做Redis

2.1 在 .net中主要使用兩個開源的組件來操做Redis

1. StackExChange.Redis:依賴的組件少,操做接近原生的Redis操做

2. ServiceStack.Redis:依賴的組件較多,封裝的程度較高

NuGet命令安裝組件 Install-Package StackExChange.Redis

 

2.2  操做字符串類型的數據

 //建立一個鏈接,寫入一個字符型數據而後讀取
public async Task<ViewResult> Index()
{    
    //建立一個Redis鏈接 由於提供了異步的方法,因此本人要玩一個騷操做
    using (ConnectionMultiplexer conn = await ConnectionMultiplexer.ConnectAsync("***.**.**.***:6379"))
    {
        IDatabase db = conn.GetDatabase();
        //往Redis裏面寫入一個Key爲name的字符串
        bool flag= await db.StringSetAsync("name","123");
        //讀取數據
        var a= db.StringGet("name");
    }
    return View();
}    

  

//String類型能夠用做計數器
public async  Task<ViewResult> Index()
{
    using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect("120.25.161.171:6379,abortConnect = false"))
    {
        IDatabase db = conn.GetDatabase();
        //StringAppend向這個key的字符串追加內容,沒有則建立,返回該字符串
        var A = db.StringAppend("敢問是段友?","yes yes yes");
        //StringIncrementAsync計數器,從0開始自加1,沒有則從0開始,返回計數後的結果
        long a = await db.StringIncrementAsync("天王蓋地虎",1);
        long b = Convert.ToInt64( db.StringGet("天王蓋地虎"));
        long c =  db.StringDecrement("清風拂楊柳", 1);
    }
    return View();
}

  

2.3 操做List類型數據

 public async  Task<ViewResult> Index()
{
    using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect("***.**.***.***:6379,abortConnect = false"))
    {
        IDatabase db = conn.GetDatabase();
        for (int i = 0; i < 20; i++)
        {
           //往集合u哦便Push數據
           var a= await db.ListLeftPushAsync("List1", ""+i+"");
        }
        //往集合右邊Pop數據Pop讀取了數據後數據會從集合中移除(消息隊列)
        RedisValue b = db.ListRightPop("List1");
        //讀取集合中所有數據,不會將數據移除
        RedisValue[] c =await db.ListRangeAsync("List1");
    }
    return View();
}

  

2.5  Hash

value 又是一個「鍵值對集合」或者值是另一個 Dictionary。 

 

2.6 SortedSet類型的數據

若是對於數據遍歷順序有要求,可使用 sortedset,他會按照打分來進行遍歷。 

 public async  Task<ViewResult> Index()
{
    using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect("120.25.161.171:6379,abortConnect = false"))
    {
        IDatabase db = conn.GetDatabase();
        //SortedSetIncrement 用於給Set數據的vaule排序
        for (int i = 0; i < 5; i++)
        {
            var a = db.SortedSetIncrement("resou","小熊vs",1);
        }
        for (int i = 0; i < 3; i++)
        {
            var b = db.SortedSetIncrement("resou", "田伯光", 1);
        }
        for (int i = 0; i <6; i++)
        {
            var c = db.SortedSetIncrement("resou", "段正淳", 1);
        }

        SortedSetEntry[] d= db.SortedSetRangeByRankWithScores("resou");
        foreach (var item in d)
        {
            Console.WriteLine(item);
        }
        //根據排序返回值,能夠根據序號查詢其中一部分;
        //RedisValue[] SortedSetRangeByRank(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending) 
        //根據排序返回值,能夠只返回 start-stop 這個範圍; 
        //RedisValue[] SortedSetRangeByScore(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1) 
    }
    return View();
}

  

2.5 Geo數據類型的基本操做

Geo 是 Redis 3.2 版本後新增的數據類型,用來保存興趣點(POI,point of interest)的座標信息。 能夠實現計算兩 POI 之間的距離、獲取一個點周邊指定距離的 POI。

public async  Task<ViewResult> Index()
{
    using (ConnectionMultiplexer conn = ConnectionMultiplexer.Connect("120.25.161.171:6379,abortConnect = false"))
    {
        IDatabase db = conn.GetDatabase();
        //添加一個興趣點
        db.GeoAdd("hehe", new GeoEntry(11.22,12.23,"1"));
        db.GeoAdd("hehe", new GeoEntry(11.32, 12.23, "2"));
        db.GeoAdd("hehe", new GeoEntry(11.42, 12.23, "3"));
        //根據點的主鍵獲取座標
        GeoPosition? pos = db.GeoPosition("ShopsGeo", "1");
        //計算兩個興趣點之間的距離
        var a= db.GeoDistance("hehe","1","3",GeoUnit.Meters);
        //計算某個興趣點範圍內其他的興趣點
        GeoRadiusResult[] grr= db.GeoRadius("hehe",1,10000,GeoUnit.Meters);
        //計算一個經緯度範圍內的距離
        GeoRadiusResult[] grr2 = db.GeoRadius("hehe", 11.42, 12.23,1000, GeoUnit.Meters);
        foreach (var item in grr)
        {
           Console.WriteLine(item.Member + ":" + item.Distance + "米");
        }
    }
    return View();
}

  

三 Redis批量操做

 若是一次性執行多個Redis操做不少那麼會很慢,可使用批量操做。

主要有兩種方式:

1) 幾乎全部的操做都支持數組類型,這樣就能夠一次性操做多條數據:好比 GeoAdd(RedisKey key, GeoEntry[] values)、SortedSetAdd(RedisKey key, SortedSetEntry[] values)

2) 若是一次性的操做不是簡單的同類型操做,那麼就要使用批量模式:

IBatch batch = db.CreateBatch(); db.GeoAdd("ShopsGeo1", new GeoEntry(116.34039, 39.94218, "1")); db.StringSet("abc", "123"); batch.Execute(); 

會把當前鏈接的 CreateBatch()、Execute()之間的操做一次性提交給服務器。 

相關文章
相關標籤/搜索