C#版-Redis緩存服務器在Windows下的使用

Redis緩存服務器是一款key/value數據庫,讀110000次/s,寫81000次/s,由於是內存操做因此速度飛快,常見用法是存用戶token、短信驗證碼等git

官網顯示Redis自己並無Windows版本的,微軟官方開發了基於Windows的Redis服務器:MSOpenTech/redis github

1、Redis服務端

 

首先下載Redis服務器,點擊前往下載.msi版本,雙擊安裝Redis服務端就有了,並以服務的形式隨系統一塊兒啓動: redis

 

安裝好Redis服務器以後第一件事就是設置密碼,進入安裝目錄:C:\Program Files\Redis - 找到配置文件:redis.windows-service.conf - 找到:# requirepass foobared - 回車換行加上:requirepass 這裏寫本身的新密碼(頂行寫,前面不要留空格) - 到服務裏重啓Redis服務,或者重啓電腦數據庫

不設置密碼的壞處,看看攜程這哥們的遭遇就知道了:記一次Redis被攻擊的事件 windows

2、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) post

keys *:查看全部鍵值對(若是Redis服務器設置了密碼,這條命令會報錯,須要先輸入密碼,執行此命令:auth 你的密碼) ui

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(https://redisdesktop.com/download)

 

左側樹顯示已經有一個鏈接了,點擊底部的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系統 

3、C#操做Redis服務器 

以上都是命令行和可視化工具操做Redis服務器,C#程序操做Redis須要藉助StackExchange.Redis(https://github.com/StackExchange/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;
       }
   }

}

向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的記錄");
}

 4、其餘 

MSOpenTech開發Redis緩存服務器自帶持久化,寫入以後重啓電腦鍵值對還存在,通常寫入鍵值對要設置過時時間,不然一直佔用內存不會被釋放。Redis存儲方式不光有鍵對應字符串,還有對應List,HashTable等,固然Redis更多高階的用法仍是在Linux下。

相關文章
相關標籤/搜索