一、簡介
Redis是著名的NOSQL數據庫,本質就是存儲鍵值對結構的數據,為存儲鍵值對數據做了優化,在大型網站中應用很多。Redis提供了數據的自動過期處理,因此適合存儲臨時數據。
和Redis類似的還有Memcached, Redis可以把數據持久化到硬盤中,而Memcached是放到內存中,重啟后就消失,一般用Memcached做緩存。
二、Redis服務器的部署(Windows)
Redis服務器有Linux、Windows版,Linux版性能好適合生產環境。這里只說明Windows里配置Redis服務器,用于開發。
1.安裝Redis服務
文件下載:redisbin_x32
安裝路徑不要包含中文或其他特殊符號,解壓后服務相關文件如下:
redis-server.exe單擊該文件雖然可以開啟服務,但是要一直保證這個文件不能關閉,雙擊點開如圖:
2.把Redis服務配置到Windows服務里
說明:配置此項后,不必去通過找到“redis-server.exe”文件單擊打開一直掛著,才能使用服務。
文件下載:RedisWatcher1
解壓安裝后相關文件如下:
修改“watcher.conf”文件里,打開文件,進行圖片說明的操作
修改后去Windows服務里開啟Redis服務,如圖:
三、在.net中操作Redis
1.在項目中導入相關的.dll文件的引用
文件下載:Redis.Net驅動
相關.dll如圖:
2.創建一個RedisManage類
寫入以下關鍵代碼:

1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace Redis_Test 9 { 10 class RedisManage 11 { 12 13 public static PooledRedisClientManager ClientManager { get; private set; } 14 static RedisManage() 15 { 16 RedisClientManagerConfig redisConfig = new RedisClientManagerConfig(); 17 redisConfig.MaxWritePoolSize = 128; 18 redisConfig.MaxReadPoolSize = 128; 19 20 //可以讀寫分離,指定一臺服務器讀,一臺寫。 21 // new PooledRedisClientManage(讀寫的服務器地址,只讀的服務器地址 22 ClientManager = new PooledRedisClientManager(new string[] { "127.0.0.1" }, 23 new string[] {"127.0.0.1"}, redisConfig); 24 } 25 26 27 } 28 }
3.存儲信息的方法
1 2 using (IRedisClient con = RedisManage.ClientManager.GetClient()) 3 { 4 //存數據 5 con.Set<int>("age", 18); 6 Dictionary<string, string> dic = new Dictionary<string, string>(); 7 dic["yzk"] = "test"; 8 con.Set<Dictionary<string, string>>("dic", dic); 9 10 }
4.讀取數據
1 using (IRedisClient con = RedisManage.ClientManager.GetClient()) 2 { 3 //取數據 4 int age = con.Get<int>("age"); 5 Console.WriteLine(age); 6 Dictionary<string, string> dic = con.Get<Dictionary<string, string>>("dic"); 7 Console.WriteLine(dic["yzk"]); 8 9 }
5. 支持寫入數據設置超時:
bool Set<T>(string key, T value, DateTime expiresAt);
第三個參數DateTime,可以指定數據到期時間,到期數據將不存在服務器里
四、在項目解決的一些問題
1.同一個用戶名只能在一臺電腦或者一個瀏覽器中登陸,嚴格來說是一個Session,Web中很難區別是否是同一臺電腦,
這里的本質是使用用戶名與SessionID進行鍵值對關聯,存儲到Redis中。
技術思路:在編寫用戶登陸代碼處,將用戶名(唯一)做為鍵,當前的SessionId作為值,存儲到Redis數據庫中。然后在每次請求頁面時,
就把當前SessionID取出,在把對應的Redis中的SessionId取出,兩者進行比較,假如這時用戶已經換了瀏覽器登陸,那么Redis中對應的SessionID將覆蓋了,
兩者不對等,那么就證明該用戶在其他地方進行了登陸。
俗語:但凡登陸就要用當前SessionID覆蓋Redis中的SessionID,只要每當請求,發現當前SessionID與Redis中的不同,該頁面就要清除登陸,清除Session,說明這個用戶去了其他位置登陸了。
代碼參考,登錄成功某處:
1 context.Session["user"] = model; 2 //用戶名與SessionId鍵值對關系存儲到Redis中 3 using (var con = RedisManage.ClientManager.GetClient()) 4 { 5 //存數據 6 con.Set<string>(model.username,context.Session.SessionID); 7 8 }
由于,用戶每次請求頁面都要檢查,我將此操作配置到Global文件中:
參考代碼:

1 using Common; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Security; 7 using System.Web.SessionState; 8 using Model; 9 namespace rupeng 10 { 11 public class Global : System.Web.HttpApplication 12 { 13 14 public override void Init() 15 { 16 base.Init(); 17 //必須到Init()中監聽 18 //每個需要Seesion頁面啟動都會執行AcquireRequestState事件 19 //AcquireRequestState事件執行的時候Session已經準備好了 20 this.AcquireRequestState += Global_AcquireRequestState; 21 } 22 23 void Global_AcquireRequestState(object sender, EventArgs e) 24 { 25 if (HttpContext.Current.Session==null) 26 { 27 return; 28 } 29 30 31 if (Context.Session["user"]==null) //排除用戶沒有登錄 32 { 33 return; 34 } 35 user_guest model= Context.Session["user"] as user_guest; 36 using (var con = RedisManage.ClientManager.GetClient()) 37 { 38 string redis_sId = con.Get<string>(model.username); 39 40 //發現不對等,用戶在其他位置登陸了,銷毀當前Seesion 41 if (redis_sId!=Context.Session.SessionID) 42 { 43 Context.Session.Clear(); 44 Context.Session.Abandon(); 45 } 46 47 } 48 49 50 } 51 52 53 protected void Application_Start(object sender, EventArgs e) 54 { 55 56 } 57 58 protected void Session_Start(object sender, EventArgs e) 59 { 60 61 } 62 63 protected void Application_BeginRequest(object sender, EventArgs e) 64 { 65 66 } 67 68 protected void Application_AuthenticateRequest(object sender, EventArgs e) 69 { 70 71 } 72 73 protected void Application_Error(object sender, EventArgs e) 74 { 75 76 } 77 78 protected void Session_End(object sender, EventArgs e) 79 { 80 81 } 82 83 protected void Application_End(object sender, EventArgs e) 84 { 85 86 } 87 } 88 }
文章列表