C# 讀寫redis C#讀寫實時數據庫


引用: https://www.cnblogs.com/dathlin/p/9998013.html

本文將使用一個gitHub開源的組件技術來讀寫redis數據,使用的是基於以太網的TCP/IP實現,不需要額外的組件,讀取操作只要放到后台線程就不會卡死線程,本組件支持超級方便的高性能讀寫操作

github地址:https://github.com/dathlin/HslCommunication      fork      star                 如果喜歡可以star或是fork,還可以打賞支持。

官網地址:http://www.hslcommunication.cn/    

聯系作者及加群方式(激活碼在群里發放):http://www.hslcommunication.cn/Cooperation 

 

 

Redis是什么?


 這個是一個實時的數據庫技術,主要采用鍵值操作來存儲數據的。官網是 https://redis.io/ ,官方的解釋為(摘自百度百科):

 

redis是一個key-value 存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list( 鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些 數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了 memcached這類key/value存儲的不足,在部 分場合可以對關系數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。  [1] 
Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹復制。存盤可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗余很有幫助。
redis的官網地址,非常好記,是redis.io。(特意查了一下,域名后綴io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)
目前,Vmware在資助着redis項目的開發和維護。

 

安裝redis服務器


我們在使用前需要安裝服務器,一般的windows的服務器來自於微軟的項目:

https://github.com/MicrosoftArchive/redis/releases

雖然微軟的項目只更新到了 redis3.2 版本。但是已經足夠我們日常的使用了。

 

安裝完成后,會自動的啟動服務器。我們可以打開cmd來測試

 

 

服務器搭好后就可以使用C#來操作了。

再次隨便聊聊,C#有個還可以的redis類庫叫StackExchange.Redis

https://github.com/StackExchange/StackExchange.Redis

但是這個類庫呢,總有些莫名其妙的問題,尤其是超時問題,始終沒有得到很好的解決,所以我集成實現了redis的基本操作,給大家一個更多的選擇。支持.net framework和.net standard

 

當你的程序實現了redis之后,程序架構變成了:

此處的redis相當於高速的數據緩存,可以部署在服務器的電腦上,可以部署在雲端等等,任意其他的電腦上面。

接下來演示使用HSL來進行操作

 

從NUGET安裝


 

 

1
Install-Package HslCommunication

  

 

關於兩種模式


在PLC端,包括三菱,西門子,歐姆龍,AB以及Modbus Tcp客戶端的訪問器上,都支持兩種模式,短連接模式和長連接模式,現在就來解釋下什么原理。

短連接:每次讀寫都是一個單獨的請求,請求完畢也就關閉了,如果服務器的端口僅僅支持單連接,那么關閉后這個端口可以被其他連接復用,但是在頻繁的網絡請求下,容易發生異常,會有其他的請求不成功,尤其是多線程的情況下。

長連接:創建一個公用的連接通道,所有的讀寫請求都利用這個通道來完成,這樣的話,讀寫性能更快速,即時多線程調用也不會影響,內部有同步機制。如果服務器的端口僅僅支持單連接,那么這個端口就被占用了,比如三菱的端口機制,西門子的Modbus tcp端口機制也是這樣的。以下代碼默認使用長連接,性能更高,還支持多線程同步。

在短連接的模式下,每次請求都是單獨的訪問,所以沒有重連的困擾,在長連接的模式下,如果本次請求失敗了,在下次請求的時候,會自動重新連接服務器,直到請求成功為止。另外,盡量所有的讀寫都對結果的成功進行判斷。

 

 

DEMO示例:


 

下面的一個項目是這個組件的訪問測試項目,您可以進行初步的訪問的測試。該項目位於本篇文章開始處的Gitbub源代碼里面的

DEMO的開源地址:https://github.com/dathlin/HslRedisDesktop

 

 

 

 

 

可以用來瀏覽你的redis到底有什么數據,以及這個數據是什么,初步支持了  string,list,hash 數據類型。

當你寫入的key名字帶有:(英文狀態)時。這個瀏覽器還會對數據進行分類整理、

 

關於redis指令


 

http://doc.redisfans.com/index.html

 

 

原生的指令有很多,這個庫里也是支持了大部分的操作,如果你需要的功能還沒有支持,比如 獲取一個鍵的數據信息, 將指令參數按照空格輸入進去就行

1
2
3
4
5
6
7
8
9
10
11
12
13
private  void  button16_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ReadCustomer( "GET A"  );
     if  (read.IsSuccess)
     {
         // read.Content 就是從服務器返回的數據 例如為 $2\r\n11\r\n  需要自己提煉真實的數據
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  

 

 

 下面列舉一些示例

 

 

 

簡單使用


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Threading.Tasks;
using  System.Windows.Forms;
using  HslCommunication.Enthernet.Redis;
using  HslCommunication;
 
namespace  WindowsFormsApp3
{
     public  partial  class  Form1 : Form
     {
         public  Form1( )
         {
             InitializeComponent( );
         }
 
 
         private  RedisClient redisClient =  new  RedisClient(  "127.0.0.1" , 6379,  ""  );
         private  void  button1_Click(  object  sender, EventArgs e )
         {
             OperateResult< string > read = redisClient.ReadKey(  "a"  );
             if  (read.IsSuccess)
             {
                 MessageBox.Show( read.Content );
             }
             else
             {
                 MessageBox.Show( read.Message );
             }
         }
     }
}

  

結果如下:

 

顯示的值就是我們之前寫入的操作,主要,redis區分大小寫,你讀  A  和讀 a 是不一樣的。

上述的代碼已經進行了嚴格的驗證,上面情況會讀取失敗呢?網絡異常或是 a 不存在

 

我們來看看寫入鍵值:

1
2
3
4
private  void  button2_Click(  object  sender, EventArgs e )
{
     OperateResult write = redisClient.WriteKey(  "a" "abcde"  );
}

 

上述就沒有對寫入成功與否進行驗證,只要是網絡正常基本都是成功的。

寫完后我們再讀取一次:

 

 

 

如果想寫入一個有生命周期的key,比如100s后自動消失的key

1
2
3
4
private  void  button3_Click(  object  sender, EventArgs e )
{
     OperateResult write = redisClient.WriteExpireKey(  "b" "abcde" , 100 );
}

 

這樣就寫入了一個帶生命周期的key了。

 

批量讀寫


 

 如果想要一次性寫入或是讀取很多鍵值:

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button4_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ReadKey(  new  string [] {  "a" "b"  } );
     if  (read.IsSuccess)
     {
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

寫入的操作如下:

1
2
3
4
private  void  button5_Click(  object  sender, EventArgs e )
{
     redisClient.WriteKey(  new  string [] {  "a" "b"  },  new  string [] {  "abcde" "ihsdasd"  } );
}

此處省略了對寫入結果的驗證,為了安全起見,你應該添加。

 

獲取舊值,並設置一個新的值進去

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button6_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ReadAndWriteKey(  "a" "aaaaaa"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  

 遞增遞減操作。


 

 這個基本功能也是很常見的、

我們先寫 BB 為 0

 

 然后我們再給這個值加1,並返回1的操作。

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button7_Click(  object  sender, EventArgs e )
{
     OperateResult< int > read = redisClient.IncrementKey(  "BB"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show(  "Value:"  + read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

同理也支持減一操作,增加指定的數據操作,減去指定的數據操作。

 

 

 

 

列表操作


 

redis也支持存儲數組數據信息

我們創建一個數組,並往里面塞東西,當然支持從數組的左側塞,也支持從右側塞,下面就是左側的例子

1
2
3
4
private  void  button8_Click(  object  sender, EventArgs e )
{
     redisClient.ListLeftPush(  "C" "123"  );
}

這樣就創建了一個數組,數組數據的讀取,並不是get了,而是變成了 LRANGE 0 -1 代表讀取整個的數組

 

用代碼來讀取就是

1
2
3
4
5
6
7
8
9
10
11
12
13
private  void  button9_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ListRange(  "C" , 0, -1 );
     if  (read.IsSuccess)
     {
         // 列表變成了一個數組信息
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

 

當然,當你的數組很大時。比如1000個長度時,你可以讀取中間任意個數組。

 

獲取數組長度


 

 當你不知道一個數組的長度,不想在讀取所有的數組信息的情況下,讀取到長度

1
2
3
4
private  void  button10_Click(  object  sender, EventArgs e )
{
     int  length = redisClient.GetListLength(  "C"  ).Content;  // 此處就是1
}

 

獲取指定索引的數據


 

1
2
3
4
private  void  button11_Click(  object  sender, EventArgs e )
{
     string  read = redisClient.ReadListByIndex(  "C" , 0 ).Content;
}

 

注意,當C不是list時,會引發錯誤。  

 

 

修剪列表信息


當數組過長時,我們可以修剪數組來達到收縮的目的

1
2
3
4
private  void  button12_Click(  object  sender, EventArgs e )
{
     redisClient.ListTrim(  "C" , 0, 9 ); // 10個長度,保留0-9索引的數據
}

  

 

返回並移除開始處的列表


 

 

1
2
3
4
5
6
7
8
9
10
11
12
private  void  button13_Click(  object  sender, EventArgs e )
{
     OperateResult< string > read = redisClient.ListLeftPop(  "C"  );
     if  (read.IsSuccess)
     {
         MessageBox.Show( read.Content );
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}

  移除並返回測試的也是可以的。

 

 

 

哈希值讀寫


 

哈希值的意思是一個鍵的值是由多個鍵值組成的

1
2
3
4
5
6
private  void  button14_Click(  object  sender, EventArgs e )
{
     redisClient.WriteHashKey(  "D" "A" "1"  );
     redisClient.WriteHashKey(  "D" "B" "2"  );
     redisClient.WriteHashKey(  "D" "C" "3"  );
}

  

相當於是鍵 D 的域 A 寫入1, B寫入2,C寫入3

你一次可以讀取所有的C的域集合,或是值集合,或是域+值集合,下面演示了一個示例,讀取域+值集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private  void  button15_Click(  object  sender, EventArgs e )
{
     OperateResult< string []> read = redisClient.ReadHashKeyAll(  "C"  );
     if  (read.IsSuccess)
     {
         // 列表變成了一個域+值信息
         // A
         // 1
         // B
         // 2
         // C
         // 3
         string [] result = read.Content;
     }
     else
     {
         MessageBox.Show( read.Message );
     }
}


免責聲明!

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



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