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));
}));
}
}