- A+
所属分类:.NET技术
1. 缓存是什么,各级缓存
2. 本地缓存原理和实现
3. 缓存应用和缓存更新
缓存:为了快速获取结果,在第一次获取数据后存起来,下次直接使用
缓存一般用在哪里?
1. 会重复的请求
2. 数据相对稳定
3. 耗时/耗资源
4. 体积不大
配置文件;菜单-权限;省市区;类别数据;
热搜;公告;技能/属性;数据字典;
分页(只要数据不是经常变)
如果一个数据缓存一次,能够被有效查询4次,那这个缓存就是值得的(大型系统的时候,为了性能,为了压力,需要更多的缓存)
缓存本身是共享的,所以每个缓存应该是唯一的
本地缓存空间小,不能跨进程共享
小项目一般随便缓存
中大型项目不够用的,一般就会使用分布式缓存
如:
Memcached:内存管理
Redis: REmote DIctionary Server
下面附上我学习使用的自建简单Cahce缓存代码:
public class CustomeCache { /// <summary> /// 线程安全的Dictionary集合 /// </summary> public static Dictionary<string, KeyValuePair<object, DateTime>> CustomCacheDictionary; /// <summary> /// 缓存需要自动清理:防止过多无用缓存 /// </summary> static CustomeCache() { CustomCacheDictionary = new Dictionary<string, KeyValuePair<object, DateTime>>(); Console.WriteLine($"{DateTime.Now.ToString("MM-dd HH:mm:ss fff")}初始化缓存"); Task.Run(() => { while (true) { LockAction(new Action(() => { List<string> list = new List<string>(); foreach (var key in CustomCacheDictionary.Keys) { var valueTime = CustomCacheDictionary[key]; if (valueTime.Value > DateTime.Now) { //没有过期就不用管 } else { //过期就统一将key放入list中 list.Add(key); } } list.ForEach(key => CustomCacheDictionary.Remove(key)); })); Thread.Sleep(1000 * 60 * 15);//每15分钟清理一次 } }); } private static readonly object CustomCache_Lock = new object(); public static void LockAction(Action action) { lock (CustomCache_Lock) { action.Invoke(); } } /// <summary> /// 添加缓存数据 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="second"></param> public static void Add(string key, object value, int second = 1800) { LockAction(new Action(() => { CustomCacheDictionary.Add(key, new KeyValuePair<object, DateTime>(value, DateTime.Now.AddSeconds(second))); })); } /// <summary> /// 保存数据 -存在则更新 不存在则新增 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="second"></param> public static void SaveOrUpdate(string key, object value, int second = 1800) { LockAction(new Action(() => { CustomCacheDictionary[key] = new KeyValuePair<object, DateTime>(value, DateTime.Now.AddSeconds(second)); })); } public static T Find<T>(string key, Func<T> func, int second = 1800) { T t = default(T); if (!Exsit(key)) { t = func.Invoke(); CustomeCache.Add(key, t, second); } else { t = Get<T>(key); } return t; } /// <summary> /// 获取数据 没有则异常 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public static T Get<T>(string key) { return (T)CustomCacheDictionary[key].Key; } /// <summary> /// 检查是否存在 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Exsit(string key) { if (CustomCacheDictionary.ContainsKey(key)) { var valueTime = CustomCacheDictionary[key]; if (valueTime.Value > DateTime.Now) { //时候未到 return true; } else { //时晨已到 上台 LockAction(new Action(() => { CustomCacheDictionary.Remove(key); })); return false; } } else { return false; } } public static void Remove(string key) { LockAction(new Action(() => { CustomCacheDictionary.Remove(key); })); } public static void RemoveAll() { LockAction(new Action(() => { CustomCacheDictionary.Clear(); })); } public static void RemoveCondition(Func<string, bool> func) { LockAction(new Action(() => { List<string> list = new List<string>(); foreach (var key in CustomCacheDictionary.Keys) { if (func.Invoke(key)) { list.Add(key); } } list.ForEach(key => CustomCacheDictionary.Remove(key)); })); } }