緩存技術Redis在C#中的使用及Redis的封裝,
Redis是一款開源的、高性能的鍵-值存儲(key-value store)。它常被稱作是一款數據結構服務器(data structure server)。Redis的鍵值可以包括字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等數據類型。 對於這些數據類型,你可以執行原子操作。例如:對字符串進行附加操作(append);遞增哈希中的值;向列表中增加元素;計算集合的交集、並集與差集 等。
為了獲得優異的性能,Redis采用了內存中(in-memory)數據集(dataset)的方式。根據使用場景的不同,你可以每隔一段時間將數據集轉存到磁盤上來持久化數據,或者在日志尾部追加每一條操作命令。
Redis同樣支持主從復制(master-slave
replication),並且具有非常快速的非阻塞首次同步(non-blocking first
synchronization)、網絡斷開自動重連等功能。同時Redis還具有其它一些特性,其中包括簡單的check-and-set機制、
pub/sub和配置設置等,以便使得Redis能夠表現得更像緩存(cache)。
Redis還提供了豐富的客戶端,以便支持現階段流行的大多數編程語言。詳細的支持列表可以參看Redis官方文檔:http://redis.io
/clients。Redis自身使用ANSI C來編寫,並且能夠在不產生外部依賴(external
dependencies)的情況下運行在大多數POSIX系統上,例如:Linux、*BSD、OS X和Solaris等。
Redis 由四個可執行文件:redis-benchmark、redis-cli、redis-server、redis-stat 這四個文件,加上一個redis.conf就構成了整個redis的最終可用包。它們的作用如下:
redis-server:Redis服務器的daemon啟動程序
redis-cli:Redis命令行操作工具。當然,你也可以用telnet根據其純文本協議來操作
redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能
redis-stat:Redis狀態檢測工具,可以檢測Redis當前狀態參數及延遲狀況
現在就可以啟動redis了,redis只有一個啟動參數,就是他的配置文件路徑。
首選,你先得開啟redis-server,否則無法連接服務:
打開redis-server:
接下來你就可以調用Redis的屬性來進行數據的存儲及獲取:
關鍵性代碼:
[csharp] view plain copy print?
- <span >using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using ServiceStack.Redis;
- using ServiceStack.Redis.Support;
-
- namespace RedisStudy
- {
- class Program
- {
- static void Main(string[] args)
- {
- try
- {
- //獲取Redis操作接口
- IRedisClient Redis = RedisManager.GetClient();
- //Hash表操作
- HashOperator operators = new HashOperator();
-
- //移除某個緩存數據
- bool isTrue = Redis.Remove("additemtolist");
-
- //將字符串列表添加到redis
- List<string> storeMembers = new List<string>() { "韓梅梅", "李雷", "露西" };
- storeMembers.ForEach(x => Redis.AddItemToList("additemtolist", x));
- //得到指定的key所對應的value集合
- Console.WriteLine("得到指定的key所對應的value集合:");
- var members = Redis.GetAllItemsFromList("additemtolist");
- members.ForEach(s => Console.WriteLine("additemtolist :" + s));
- Console.WriteLine("");
-
- // 獲取指定索引位置數據
- Console.WriteLine("獲取指定索引位置數據:");
- var item = Redis.GetItemFromList("additemtolist", 2);
- Console.WriteLine(item);
-
- Console.WriteLine("");
-
- //將數據存入Hash表中
- Console.WriteLine("Hash表數據存儲:");
- UserInfo userInfos = new UserInfo() { UserName = "李雷", Age = 45 };
- var ser = new ObjectSerializer(); //位於namespace ServiceStack.Redis.Support;
- bool results = operators.Set<byte[]>("userInfosHash", "userInfos", ser.Serialize(userInfos));
- byte[] infos = operators.Get<byte[]>("userInfosHash", "userInfos");
- userInfos = ser.Deserialize(infos) as UserInfo;
- Console.WriteLine("name=" + userInfos.UserName + " age=" + userInfos.Age);
-
- Console.WriteLine("");
-
- //object序列化方式存儲
- Console.WriteLine("object序列化方式存儲:");
- UserInfo uInfo = new UserInfo() { UserName = "張三", Age = 12 };
- bool result = Redis.Set<byte[]>("uInfo", ser.Serialize(uInfo));
- UserInfo userinfo2 = ser.Deserialize(Redis.Get<byte[]>("uInfo")) as UserInfo;
- Console.WriteLine("name=" + userinfo2.UserName + " age=" + userinfo2.Age);
-
- Console.WriteLine("");
-
- //存儲值類型數據
- Console.WriteLine("存儲值類型數據:");
- Redis.Set<int>("my_age", 12);//或Redis.Set("my_age", 12);
- int age = Redis.Get<int>("my_age");
- Console.WriteLine("age=" + age);
-
- Console.WriteLine("");
-
- //序列化列表數據
- Console.WriteLine("列表數據:");
- List<UserInfo> userinfoList = new List<UserInfo> {
- new UserInfo{UserName="露西",Age=1,Id=1},
- new UserInfo{UserName="瑪麗",Age=3,Id=2},
- };
- Redis.Set<byte[]>("userinfolist_serialize", ser.Serialize(userinfoList));
- List<UserInfo> userList = ser.Deserialize(Redis.Get<byte[]>("userinfolist_serialize")) as List<UserInfo>;
- userList.ForEach(i =>
- {
- Console.WriteLine("name=" + i.UserName + " age=" + i.Age);
- });
- //釋放內存
- Redis.Dispose();
- operators.Dispose();
- Console.ReadKey();
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message.ToString());
- Console.WriteLine("Please open the redis-server.exe ");
- Console.ReadKey();
- }
- }
- }
- }</span>
RedisManager類:
[csharp] view plain copy print?
- <span >using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using ServiceStack.Redis;
-
- namespace RedisStudy
- {
- /// <summary>
- /// RedisManager類主要是創建鏈接池管理對象的
- /// </summary>
- public class RedisManager
- {
- /// <summary>
- /// redis配置文件信息
- /// </summary>
- private static string RedisPath = System.Configuration.ConfigurationSettings.AppSettings["RedisPath"];
- private static PooledRedisClientManager _prcm;
-
- /// <summary>
- /// 靜態構造方法,初始化鏈接池管理對象
- /// </summary>
- static RedisManager()
- {
- CreateManager();
- }
-
- /// <summary>
- /// 創建鏈接池管理對象
- /// </summary>
- private static void CreateManager()
- {
- _prcm = CreateManager(new string[] { RedisPath }, new string[] { RedisPath });
- }
-
-
- private static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
- {
- //WriteServerList:可寫的Redis鏈接地址。
- //ReadServerList:可讀的Redis鏈接地址。
- //MaxWritePoolSize:最大寫鏈接數。
- //MaxReadPoolSize:最大讀鏈接數。
- //AutoStart:自動重啟。
- //LocalCacheTime:本地緩存到期時間,單位:秒。
- //RecordeLog:是否記錄日志,該設置僅用於排查redis運行時出現的問題,如redis工作正常,請關閉該項。
- //RedisConfigInfo類是記錄redis連接信息,此信息和配置文件中的RedisConfig相呼應
-
- // 支持讀寫分離,均衡負載
- return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
- {
- MaxWritePoolSize = 5, // “寫”鏈接池鏈接數
- MaxReadPoolSize = 5, // “讀”鏈接池鏈接數
- AutoStart = true,
- });
- }
-
- private static IEnumerable<string> SplitString(string strSource, string split)
- {
- return strSource.Split(split.ToArray());
- }
-
- /// <summary>
- /// 客戶端緩存操作對象
- /// </summary>
- public static IRedisClient GetClient()
- {
- if (_prcm == null)
- {
- CreateManager();
- }
- return _prcm.GetClient();
- }
-
- }
- }</span>
RedisOperatorBase類:
[csharp] view plain copy print?
- <span >using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using ServiceStack.Redis;
-
- namespace RedisStudy
- {
- /// <summary>
- /// RedisOperatorBase類,是redis操作的基類,繼承自IDisposable接口,主要用於釋放內存
- /// </summary>
- public abstract class RedisOperatorBase : IDisposable
- {
- protected IRedisClient Redis { get; private set; }
- private bool _disposed = false;
- protected RedisOperatorBase()
- {
- Redis = RedisManager.GetClient();
- }
- protected virtual void Dispose(bool disposing)
- {
- if (!this._disposed)
- {
- if (disposing)
- {
- Redis.Dispose();
- Redis = null;
- }
- }
- this._disposed = true;
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// 保存數據DB文件到硬盤
- /// </summary>
- public void Save()
- {
- Redis.Save();
- }
- /// <summary>
- /// 異步保存數據DB文件到硬盤
- /// </summary>
- public void SaveAsync()
- {
- Redis.SaveAsync();
- }
- }
- }</span>
HashOperator類:
[csharp] view plain copy print?
- <span >using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using ServiceStack.Text;
-
- namespace RedisStudy
- {
- /// <summary>
- /// HashOperator類,是操作哈希表類。繼承自RedisOperatorBase類
- /// </summary>
- public class HashOperator : RedisOperatorBase
- {
- public HashOperator() : base() { }
- /// <summary>
- /// 判斷某個數據是否已經被緩存
- /// </summary>
- public bool Exist<T>(string hashId, string key)
- {
- return Redis.HashContainsEntry(hashId, key);
- }
- /// <summary>
- /// 存儲數據到hash表
- /// </summary>
- public bool Set<T>(string hashId, string key, T t)
- {
- var value = JsonSerializer.SerializeToString<T>(t);
- return Redis.SetEntryInHash(hashId, key, value);
- }
- /// <summary>
- /// 移除hash中的某值
- /// </summary>
- public bool Remove(string hashId, string key)
- {
- return Redis.RemoveEntryFromHash(hashId, key);
- }
- /// <summary>
- /// 移除整個hash
- /// </summary>
- public bool Remove(string key)
- {
- return Redis.Remove(key);
- }
- /// <summary>
- /// 從hash表獲取數據
- /// </summary>
- public T Get<T>(string hashId, string key)
- {
- string value = Redis.GetValueFromHash(hashId, key);
- return JsonSerializer.DeserializeFromString<T>(value);
- }
- /// <summary>
- /// 獲取整個hash的數據
- /// </summary>
- public List<T> GetAll<T>(string hashId)
- {
- var result = new List<T>();
- var list = Redis.GetHashValues(hashId);
- if (list != null && list.Count > 0)
- {
- list.ForEach(x =>
- {
- var value = JsonSerializer.DeserializeFromString<T>(x);
- result.Add(value);
- });
- }
- return result;
- }
- /// <summary>
- /// 設置緩存過期
- /// </summary>
- public void SetExpire(string key, DateTime datetime)
- {
- Redis.ExpireEntryAt(key, datetime);
- }
- }
- }</span>
UserInfo類:
[csharp] view plain copy print?
- <span >using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- namespace RedisStudy
- {
- [Serializable]
- public class UserInfo
- {
- public int Id;
- public string UserName;
- public int Age;
- }
- }</span>
app.config配置:
[csharp] view plain copy print?
- <?xml version="1.0"?>
- <configuration>
- <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
- <appSettings>
- <add key="RedisPath" value="127.0.0.1:6379"/>
- </appSettings>
- </configuration>
以上是Redis操作的封裝類,直接拿來調用即可。