C#之Redis所欲為


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

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

建議下載 .msi結尾的應用程序進行安裝,會自動安裝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()之間的操作一次性提交給服務器。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM