Redis緩存伺服器是一款key/value資料庫,讀110000次/s,寫81000次/s,因為是記憶體操作所以速度飛快,常見用法是存用戶token、簡訊驗證碼等 官網顯示Redis本身並沒有Windows版本的,微軟官方開發了基於Windows的Redis伺服器:MSOpenTech/redis ...
Redis緩存伺服器是一款key/value資料庫,讀110000次/s,寫81000次/s,因為是記憶體操作所以速度飛快,常見用法是存用戶token、簡訊驗證碼等
官網顯示Redis本身並沒有Windows版本的,微軟官方開發了基於Windows的Redis伺服器:MSOpenTech/redis
一、Redis服務端
首先下載Redis伺服器,點擊前往下載.msi版本,雙擊安裝Redis服務端就有了,並以服務的形式隨系統一起啟動:
安裝好Redis伺服器之後第一件事就是設置密碼,進入安裝目錄:C:\Program Files\Redis - 找到配置文件:redis.windows-service.conf - 找到:# requirepass foobared - 回車換行加上:requirepass 這裡寫自己的新密碼(頂行寫,前面不要留空格) - 到服務里重啟Redis服務,或者重啟電腦
不設置密碼的壞處,看看攜程這哥們的遭遇就知道了:記一次Redis被攻擊的事件
二、Redis客戶端(命令行和可視化工具RDM)
命令行方式演示:啟動Redis客戶端、讀寫Redis伺服器
上圖命令解釋:
cd C:\Program Files\Redis:cd命令進入Redis安裝目錄,相當於Windows系統里雙擊進入Redis的安裝目錄
redis-cli.exe:打開redis-cli客戶端程式,相當於Windows系統里雙擊運行一個exe程式(安裝了上面的Redis服務端程式,需要一個客戶端程式連接這個服務端。連接本機redis伺服器直接敲此命令,連接遠程的需要加ip和埠,例:redis-cli.exe -h 111.11.11.111 -p 6379)
keys *:查看所有鍵值對(如果Redis伺服器設置了密碼,這條命令會報錯,需要先輸入密碼,執行此命令:auth 你的密碼)
set blog oppoic.cnblogs.com:設置一個鍵值對,鍵是:blog,值是:oppoic.cnblogs.com(按目錄存儲:set 目錄名:鍵 值)
get blog:獲取鍵為blog對應的值
keys *:查看所有鍵值對
其他常用命令:
config get dir:獲取redis安裝目錄
ping:返回PONG表示redis伺服器正常
redis-cli.exe:進入第一個資料庫(預設),redis一共0到15共16個庫,進入第三個庫 redis-cli -n 2(已經進去了,select 0~15 隨意切換)
quit:退出redis程式
exit:退出dos視窗
flushdb:刪除當前選擇資料庫中的所有key
flushall:刪除所有資料庫中的資料庫
更多命令:https://redis.io/commands
至此,一個運行在本機的Redis緩存伺服器已經搭建完成,並且可以讀寫了。但是命令行顯然對小白用戶不友好,可視化工具登場:Redis Desktop Manager
左側樹顯示已經有一個連接了,點擊底部的Connect to Redis Server再添加一個連接:
Name:連接名稱,隨便起
Host:主機地址,本機就是127.0.0.1,遠程的輸入對應IP
Port:埠,Redis伺服器預設埠6379
Auth:密碼,設置了就輸,沒設置留空
連上Redis伺服器就可以看到,預設16個庫(配置文件可改),索引從0開始。常見用法是一個項目一個庫,項目下不同功能模塊分不同目錄存在這個庫下。
有了可視化工具之後的操作就不用說了,雙擊,右鍵新建、刪除。。。會用Windows系統的都會用這個工具。相比於命令行,Redis Desktop Manager這個可視化工具更友好,調試遠程伺服器上的數據也更方便,指哪打哪。
註:本機可以這樣,連接遠程伺服器需要到伺服器上的Redis安裝目錄下,找到redis.windows-service.conf文件,找到bind 127.0.0.1 前面加"#"註釋掉,然後到服務里右鍵重啟redis服務,或者重啟Windows系統
三、C#操作Redis伺服器
以上都是命令行和可視化工具操作Redis伺服器,C#程式操作Redis需要藉助StackExchange.Redis,為了統一調用,封裝了一個RedisHelper幫助類:
using Newtonsoft.Json; using StackExchange.Redis; using System; using System.ComponentModel; using System.Configuration; using System.Reflection; using System.Text; namespace redis_Demo { /// <summary> /// Redis 幫助類 /// </summary> public static class RedisHelper { private static string _conn = ConfigurationManager.AppSettings["redis_connection_string"] ?? "127.0.0.1:6379"; private static string _pwd = ConfigurationManager.AppSettings["redis_connection_pwd"] ?? "123456"; static ConnectionMultiplexer _redis; static readonly object _locker = new object(); #region 單例模式 public static ConnectionMultiplexer Manager { get { if (_redis == null) { lock (_locker) { if (_redis != null) return _redis; _redis = GetManager(); return _redis; } } return _redis; } } private static ConnectionMultiplexer GetManager(string connectionString = null) { if (string.IsNullOrEmpty(connectionString)) { connectionString = _conn; } var options = ConfigurationOptions.Parse(connectionString); options.Password = _pwd; return ConnectionMultiplexer.Connect(options); } #endregion /// <summary> /// 添加 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="value">值</param> /// <param name="expireMinutes">過期時間,單位:分鐘。預設600分鐘</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> /// <returns></returns> public static bool StringSet(CacheFolderEnum folder, string key, string value, int expireMinutes = 600, int db = -1) { string fd = GetDescription(folder); return Manager.GetDatabase(db).StringSet(string.IsNullOrEmpty(fd) ? key : fd + ":" + key, value, TimeSpan.FromMinutes(expireMinutes)); } /// <summary> /// 獲取 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> /// <returns></returns> public static string StringGet(CacheFolderEnum folder, string key, int db = -1) { try { string fd = GetDescription(folder); return Manager.GetDatabase(db).StringGet(string.IsNullOrEmpty(fd) ? key : fd + ":" + key); } catch (Exception) { return null; } } /// <summary> /// 刪除 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> /// <returns></returns> public static bool StringRemove(CacheFolderEnum folder, string key, int db = -1) { try { string fd = GetDescription(folder); return Manager.GetDatabase(db).KeyDelete(string.IsNullOrEmpty(fd) ? key : fd + ":" + key); } catch (Exception) { return false; } } /// <summary> /// 是否存在 /// </summary> /// <param name="key">鍵</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> public static bool KeyExists(CacheFolderEnum folder, string key, int db = -1) { try { string fd = GetDescription(folder); return Manager.GetDatabase(db).KeyExists(string.IsNullOrEmpty(fd) ? key : fd + ":" + key); } catch (Exception) { return false; } } /// <summary> /// 延期 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="min">延長時間,單位:分鐘,預設600分鐘</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> public static bool AddExpire(CacheFolderEnum folder, string key, int min = 600, int db = -1) { try { string fd = GetDescription(folder); return Manager.GetDatabase(db).KeyExpire(string.IsNullOrEmpty(fd) ? key : fd + ":" + key, DateTime.Now.AddMinutes(min)); } catch (Exception) { return false; } } /// <summary> /// 添加實體 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="t">實體</param> /// <param name="ts">延長時間,單位:分鐘,預設600分鐘</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> public static bool Set<T>(CacheFolderEnum folder, string key, T t, int expireMinutes = 600, int db = -1) { string fd = GetDescription(folder); var str = JsonConvert.SerializeObject(t); return Manager.GetDatabase(db).StringSet(string.IsNullOrEmpty(fd) ? key : fd + ":" + key, str, TimeSpan.FromMinutes(expireMinutes)); } /// <summary> /// 獲取實體 /// </summary> /// <param name="folder">目錄</param> /// <param name="key">鍵</param> /// <param name="db">庫,預設第一個。0~15共16個庫</param> public static T Get<T>(CacheFolderEnum folder, string key, int db = -1) where T : class { string fd = GetDescription(folder); var strValue = Manager.GetDatabase(db).StringGet(string.IsNullOrEmpty(fd) ? key : fd + ":" + key); return string.IsNullOrEmpty(strValue) ? null : JsonConvert.DeserializeObject<T>(strValue); } /// <summary> /// 獲得枚舉的Description /// </summary> /// <param name="value">枚舉值</param> /// <param name="nameInstead">當枚舉值沒有定義DescriptionAttribute,是否使用枚舉名代替,預設是使用</param> /// <returns>枚舉的Description</returns> private static string GetDescription(this Enum value, Boolean nameInstead = true) { Type type = value.GetType(); string name = Enum.GetName(type, value); if (name == null) { return null; } FieldInfo field = type.GetField(name); DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; if (attribute == null && nameInstead == true) { return name; } return attribute == null ? null : attribute.Description; } } }View Code
向redis伺服器第一個庫的fd1目錄里,添加一個鍵為name,值為wangjie的記錄:
RedisHelper.StringSet(CacheFolderEnum.Folder1, "name", "wangjie");
獲取這條記錄:
string key = RedisHelper.StringGet(CacheFolderEnum.Folder1, "name"); Console.WriteLine("鍵為name的記錄對應的值:" + key);
刪除這條記錄:
bool result = RedisHelper.StringRemove(CacheFolderEnum.Folder1, "name"); if (result) { Console.WriteLine("鍵為name的記錄刪除成功"); } else { Console.WriteLine("鍵為name的記錄刪除失敗"); }
查詢這條記錄是否存在:
bool ifExist = RedisHelper.KeyExists(CacheFolderEnum.Folder1, "name"); if (ifExist) { Console.WriteLine("鍵為name的記錄存在"); } else { Console.WriteLine("鍵為name的記錄不存在"); }
向redis伺服器第二個庫的fd2目錄里,添加一個鍵為sd1,值為一個對象的記錄:
Student student = new Student() { Id = 1, Name = "張三", Class = "三年二班" }; RedisHelper.Set<Student>(CacheFolderEnum.Folder2, "sd1", student, 10, 1);
獲取這個對象:
Student sdGet = RedisHelper.Get<Student>(CacheFolderEnum.Folder2, "sd1", 1); if (sdGet != null) { Console.WriteLine("Id:" + sdGet.Id + " Name:" + sdGet.Name + " Class:" + sdGet.Class); } else { Console.WriteLine("找不到鍵為sd1的記錄"); }
源碼:點擊下載
環境是VS 2013,如果跑不起來自行把cs里的代碼拷出來編譯運行
四、其他
MSOpenTech開發Redis緩存伺服器自帶持久化,寫入之後重啟電腦鍵值對還存在,一般寫入鍵值對要設置過期時間,否則一直占用記憶體不會被釋放。Redis存儲方式不光有鍵對應字元串,還有對應List,HashTable等,當然Redis更多高階的用法還是在Linux下。
爬蟲可恥,本文原始鏈接:http://www.cnblogs.com/oppoic/p/6165581.html
參考資料:
怎樣在Redis通過StackExchange.Redis 存儲集合類型List