公司一直在用.net自帶的緩存,你們都知道.net自帶緩存的缺點,就很少說了,不知道的能夠查一查,領導最近在說分佈式緩存,咱們選的是redis,領導讓我不忙的時候封裝一下,搜索了兩天,選了選第三方的插件,ServiceStack.Redis和StackExchange.Redis之前都用過,不過都是別人封裝好的,今天在往項目中整合的時候,我使用的ServiceStack.Redis版本不兼容.net 4.0,在網上找了一圈,ServiceStack.Redis對.net 4.0的支持用起來很麻煩,要改變系統引用的東西,最後放棄了,今天又拿NServiceKit.Redis從新封裝了一下,下一篇在說NServiceKit.Redis。先說說ServiceStack.Redis,ServiceStack.Redis是Redis官方推薦的C#客戶端,性能很是優越,使用也很方便,可是從v4版本已經逐漸商業化了,普通版每小時只能訪問Redis 6000次,我沒測試過,你們能夠看看這篇文章http://blog.csdn.net/u010533180/article/details/52856586,因此我放棄了ServiceStack.Redis,選擇了StackExchange.Redis,StackExchange.Redis也是開源的,這是地址:https://github.com/StackExchange/StackExchange.Redis,我使用的是.net 4.5,工具採用 vs2015, StackExchange.Redis版本是1.0.488。git
對於與Redis鏈接的配置寫法很簡單,最簡單的寫法寫個IP和端口就能夠了,如你有其餘想法本身去查資料吧。StackExchange.Redis中的核心是ConnectionMultiplexer,沒事好研究研究。這裏我只封裝了對緩存的操做,之後可能會更新其餘的。github
先說說個人想法:redis
1.定義ICache接口。json
2.Redis類和Memcached類,之後想用那個緩存修改一下配置就能夠了,很是方便。緩存
3.CacheHelper的實現。分佈式
上代碼:工具
ICache.csoop
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Common { public interface ICache { /// <summary> /// 緩存過時時間 /// </summary> int TimeOut { set; get; } /// <summary> /// 得到指定鍵的緩存值 /// </summary> /// <param name="key">緩存鍵</param> /// <returns>緩存值</returns> object Get(string key); /// <summary> /// 得到指定鍵的緩存值 /// </summary> T Get<T>(string key); /// <summary> /// 從緩存中移除指定鍵的緩存值 /// </summary> /// <param name="key">緩存鍵</param> void Remove(string key); /// <summary> /// 清空全部緩存對象 /// </summary> //void Clear(); /// <summary> /// 將指定鍵的對象添加到緩存中 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> void Insert(string key, object data); /// <summary> /// 將指定鍵的對象添加到緩存中 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> void Insert<T>(string key, T data); /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間(秒鐘)</param> void Insert(string key, object data, int cacheTime); /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間(秒鐘)</param> void Insert<T>(string key, T data, int cacheTime); /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間</param> void Insert(string key, object data, DateTime cacheTime); /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間</param> void Insert<T>(string key, T data, DateTime cacheTime); /// <summary> /// 判斷key是否存在 /// </summary> bool Exists(string key); } }
Redis.cs性能
using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Common { public class Redis : ICache { int Default_Timeout = 600;//默認超時時間(單位秒) string address; JsonSerializerSettings jsonConfig = new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }; ConnectionMultiplexer connectionMultiplexer; IDatabase database; class CacheObject<T> { public int ExpireTime { get; set; } public bool ForceOutofDate { get; set; } public T Value { get; set; } } public Redis() { this.address = ConfigurationManager.AppSettings["RedisServer"]; if (this.address == null || string.IsNullOrWhiteSpace(this.address.ToString())) throw new ApplicationException("配置文件中未找到RedisServer的有效配置"); connectionMultiplexer = ConnectionMultiplexer.Connect(address); database = connectionMultiplexer.GetDatabase(); } /// <summary> /// 鏈接超時設置 /// </summary> public int TimeOut { get { return Default_Timeout; } set { Default_Timeout = value; } } public object Get(string key) { return Get<object>(key); } public T Get<T>(string key) { DateTime begin = DateTime.Now; var cacheValue = database.StringGet(key); DateTime endCache = DateTime.Now; var value = default(T); if (!cacheValue.IsNull) { var cacheObject = JsonConvert.DeserializeObject<CacheObject<T>>(cacheValue, jsonConfig); if (!cacheObject.ForceOutofDate) database.KeyExpire(key, new TimeSpan(0, 0, cacheObject.ExpireTime)); value = cacheObject.Value; } DateTime endJson = DateTime.Now; return value; } public void Insert(string key, object data) { var jsonData = GetJsonData(data, TimeOut, false); database.StringSet(key, jsonData); } public void Insert(string key, object data, int cacheTime) { var timeSpan = TimeSpan.FromSeconds(cacheTime); var jsonData = GetJsonData(data, TimeOut, true); database.StringSet(key, jsonData, timeSpan); } public void Insert(string key, object data, DateTime cacheTime) { var timeSpan = cacheTime - DateTime.Now; var jsonData = GetJsonData(data, TimeOut, true); database.StringSet(key, jsonData, timeSpan); } public void Insert<T>(string key, T data) { var jsonData = GetJsonData<T>(data, TimeOut, false); database.StringSet(key, jsonData); } public void Insert<T>(string key, T data, int cacheTime) { var timeSpan = TimeSpan.FromSeconds(cacheTime); var jsonData = GetJsonData<T>(data, TimeOut, true); database.StringSet(key, jsonData, timeSpan); } public void Insert<T>(string key, T data, DateTime cacheTime) { var timeSpan = cacheTime - DateTime.Now; var jsonData = GetJsonData<T>(data, TimeOut, true); database.StringSet(key, jsonData, timeSpan); } string GetJsonData(object data, int cacheTime, bool forceOutOfDate) { var cacheObject = new CacheObject<object>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate }; return JsonConvert.SerializeObject(cacheObject, jsonConfig);//序列化對象 } string GetJsonData<T>(T data, int cacheTime, bool forceOutOfDate) { var cacheObject = new CacheObject<T>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate }; return JsonConvert.SerializeObject(cacheObject, jsonConfig);//序列化對象 } /// <summary> /// 刪除 /// </summary> /// <param name="key"></param> public void Remove(string key) { database.KeyDelete(key, CommandFlags.HighPriority); } /// <summary> /// 判斷key是否存在 /// </summary> public bool Exists(string key) { return database.KeyExists(key); } } }
CacheHelper.cs測試
using System; using System.Collections.Generic; namespace Common { /// <summary> /// 緩存 /// </summary> public static class Cache { private static object cacheLocker = new object();//緩存鎖對象 private static ICache cache = null;//緩存接口 static Cache() { Load(); } /// <summary> /// 加載緩存 /// </summary> /// <exception cref=""></exception> private static void Load() { try { cache = new Redis(); } catch (Exception ex) { //Log.Error(ex.Message); } } public static ICache GetCache() { return cache; } /// <summary> /// 緩存過時時間 /// </summary> public static int TimeOut { get { return cache.TimeOut; } set { lock (cacheLocker) { cache.TimeOut = value; } } } /// <summary> /// 得到指定鍵的緩存值 /// </summary> /// <param name="key">緩存鍵</param> /// <returns>緩存值</returns> public static object Get(string key) { if (string.IsNullOrWhiteSpace(key)) return null; return cache.Get(key); } /// <summary> /// 得到指定鍵的緩存值 /// </summary> /// <param name="key">緩存鍵</param> /// <returns>緩存值</returns> public static T Get<T>(string key) { return cache.Get<T>(key); } /// <summary> /// 將指定鍵的對象添加到緩存中 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> public static void Insert(string key, object data) { if (string.IsNullOrWhiteSpace(key) || data == null) return; //lock (cacheLocker) { cache.Insert(key, data); } } /// <summary> /// 將指定鍵的對象添加到緩存中 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> public static void Insert<T>(string key, T data) { if (string.IsNullOrWhiteSpace(key) || data == null) return; //lock (cacheLocker) { cache.Insert<T>(key, data); } } /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間(分鐘)</param> public static void Insert(string key, object data, int cacheTime) { if (!string.IsNullOrWhiteSpace(key) && data != null) { //lock (cacheLocker) { cache.Insert(key, data, cacheTime); } } } /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間(分鐘)</param> public static void Insert<T>(string key, T data, int cacheTime) { if (!string.IsNullOrWhiteSpace(key) && data != null) { //lock (cacheLocker) { cache.Insert<T>(key, data, cacheTime); } } } /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間</param> public static void Insert(string key, object data, DateTime cacheTime) { if (!string.IsNullOrWhiteSpace(key) && data != null) { //lock (cacheLocker) { cache.Insert(key, data, cacheTime); } } } /// <summary> /// 將指定鍵的對象添加到緩存中,並指定過時時間 /// </summary> /// <param name="key">緩存鍵</param> /// <param name="data">緩存值</param> /// <param name="cacheTime">緩存過時時間</param> public static void Insert<T>(string key, T data, DateTime cacheTime) { if (!string.IsNullOrWhiteSpace(key) && data != null) { //lock (cacheLocker) { cache.Insert<T>(key, data, cacheTime); } } } /// <summary> /// 從緩存中移除指定鍵的緩存值 /// </summary> /// <param name="key">緩存鍵</param> public static void Remove(string key) { if (string.IsNullOrWhiteSpace(key)) return; lock (cacheLocker) { cache.Remove(key); } } /// <summary> /// 判斷key是否存在 /// </summary> public static bool Exists(string key) { return cache.Exists(key); } } }