• 本地及远程二级缓存


    本地及远程二级缓存

    上周将本地缓存切换到远程缓存后,导致系统运行缓慢,经分析是一个页面反复读取缓存数据。Reveiw代码,发现是开发人员对缓存调用不够规范,导致循环调用缓存。

    代码遍布整个项目,修复成本较高,只能从底层的缓存框架解决。

    经构思,觉得在远程缓存基础上增加本地缓存,默认本地缓存超时6秒,这样基本解决一次请求,相同的缓存反复请求远程缓存问题,修改如下:

    1、请求缓存的时候,先请求本地缓存,如没有请求远程,远程有数据的时候,再本地缓存一份备份

    2、设置缓存的时候,同时设置本地和远程缓存

    3、省略本地缓存和远程缓存同步(因本地缓存设置过期时间非常短,只为了减少并发请求远程缓存,一般3-5秒左右)

    缓存接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    /// <summary>
    /// 缓存接口
    /// </summary>
    public interface ICache
    {
        /// <summary>
        /// 从缓存中取得指定键的值
        /// </summary>
        /// <param name="type">指定的类型</param>
        /// <param name="key">指定的键值</param>
        /// <returns></returns>
        object Get(Type type, string key);
        /// <summary>
        /// 从缓存中取得指定键的值
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">指定的键值</param>
        /// <returns>指定键值的值</returns>
        T Get<T>(string key);
     
        /// <summary>
        /// 从缓存中取出对象,如果没有缓存调用acquire方法
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">键值</param>
        /// <param name="acquire">如果缓存中没有对象的处理方法,处理方法</param>
        /// <param name="cacheTime">如果缓存中没有对象的处理方法设置缓存过期时间</param>
        /// <returns>指定键值的值</returns>
        T Get<T>(string key, Func<T> acquire, TimeSpan cacheTime);
     
        /// <summary>
        /// 从缓存中取出对象,如果没有缓存调用acquire方法
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">键值</param>
        /// <param name="acquire">如果缓存中没有对象的处理方法,处理方法</param>
        /// <param name="expiredTime">缓存绝对过期时间</param>
        /// <returns>指定键值的值</returns>
        T Get<T>(string key, Func<T> acquire, DateTime expiredTime);
     
        /// <summary>
        /// 从缓存中取出对象,如果没有缓存调用acquire方法
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">键值</param>
        /// <param name="acquire">如果缓存中没有对象的处理方法,处理方法</param>
        /// <param name="cacheExpiration">预先定义的缓存策略类型</param>
        /// <returns>指定键值的值</returns>
        T Get<T>(string key, Func<T> acquire, CacheExpirationTypes cacheExpiration);
     
        /// <summary>
        /// 添加一个对象到到缓存,使用缺省过期时间
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">存储到缓存中的对象</param>
        /// <param name="dependencyKeys">父键值</param>
        void Set(string key, object data, params string[] dependencyKeys);
     
        /// <summary>
        /// 添加一个对象到到缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">存储到缓存中的对象</param>
        /// <param name="slidingTime">缓存时间</param>
        /// <param name="dependencyKeys">父键值</param>
        void Set(string key, object data, TimeSpan slidingTime, params string[] dependencyKeys);
     
        /// <summary>
        /// 添加一个绝对过期时间的对象到缓存
        /// </summary>
        /// <param name="key">缓存键值</param>
        /// <param name="data">缓存对象</param>
        /// <param name="expiredTime">绝对过期时间</param>
        /// <param name="dependencyKeys">父键值</param>
        void Set(string key, object data, DateTime expiredTime, params string[] dependencyKeys);
     
        /// <summary>
        /// 添加一个对象到到缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="data">存储到缓存中的对象</param>
        /// <param name="cacheExpiration">缓存过期类型</param>
        /// <param name="dependencyKeys">父键值</param>
        void Set(string key, object data, CacheExpirationTypes cacheExpiration, params string[] dependencyKeys);
     
        /// <summary>
        /// 添加文件依赖对象到缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="value">存储到缓存中的对象</param>
        /// <param name="dependencyFiles">依赖文件项</param>
        void SetFile(string key, object value, params string[] dependencyFiles);
     
        /// <summary>
        /// 添加文件依赖对象到缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="value">存储到缓存中的对象</param>
        /// <param name="expiredTime">绝对过期时间</param>
        /// <param name="dependencyFiles">依赖文件项</param>
        void SetFile(string key, object value, DateTime expiredTime, params string[] dependencyFiles);
     
        /// <summary>
        /// 添加文件依赖对象到缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <param name="value">存储到缓存中的对象</param>
        /// <param name="slidingTime">缓存持续时间</param>
        /// <param name="dependencyFiles">依赖文件项</param>
        void SetFile(string key, object value, TimeSpan slidingTime, params string[] dependencyFiles);
     
        /// <summary>
        /// 判断是否已经缓存
        /// </summary>
        /// <param name="key">键值</param>
        /// <returns>是否存在</returns>
        bool IsSet(string key);
     
        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="key">键值</param>
        void Remove(string key);
     
        /// <summary>
        /// 按模式移除缓存
        /// </summary>
        /// <param name="pattern">正则表达式模式</param>
        void RemoveByPattern(string pattern);
     
        /// <summary>
        /// 清空缓存
        /// </summary>
        void Clear();
    }

    修改的Redis缓存Get方法

     View Code

    /// <summary>
    /// 从缓存中取得指定键的值
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    /// <param name="key">指定的键值</param>
    /// <returns>指定键值的值</returns>
    public T Get<T>(string key)
    {
    key = GetKey(key);
    if (_useLocal)
    {
    //先从本地获取缓存
    var localValue = _localCache.Get(key);
    if (localValue != null)
    {
    if (_debug)
    Trace.WriteLine("Redis Cache Get from local:{0},Result:{1}".FormatWith(key, localValue.ToJson()));

    return TypeConvert.ChangeType<T>(localValue);
    }
    }

    Open();
    var value = _connection.Strings.GetString(_dbNumber, key);
    var jsonValue = _connection.Wait(value);
    Trace.WriteLine("get:{0},result:{1}".FormatWith(key, jsonValue));
    if (string.IsNullOrWhiteSpace(jsonValue))
    {
    RemoveKeyDependency(key);
    return default(T);
    }

    var cachedValue = jsonValue.FromJson<T>();

    if (_useLocal)
    {
    //设置本地缓存
    _localCache.Set(key, cachedValue, DateTime.Now + TimeSpan.FromSeconds(_defaultLocalExpiredTime));
    }

    return cachedValue;
    }


    Set方法

     View Code

    /// <summary>
    /// 添加一个对象到到缓存
    /// </summary>
    /// <param name="key">键值</param>
    /// <param name="data">存储到缓存中的对象</param>
    /// <param name="slidingTime">缓存时间</param>
    /// <param name="dependencyKeys"> </param>
    public void Set(string key, object data, TimeSpan slidingTime, params string[] dependencyKeys)
    {
    key = GetKey(key);
    if (data == null)
    {
    Remove(key);
    return;
    }

    if (_useLocal)
    {
    //设置本地缓存
    _localCache.Set(key, data,DateTime.Now + TimeSpan.FromSeconds(_defaultLocalExpiredTime));
    }

    Open();
    _connection.Strings.Set(_dbNumber, key, data.ToJson(), (long)slidingTime.TotalSeconds);
    Trace.WriteLine("Set:{0},value:{1}".FormatWith(key, data.ToJson()));
    if (dependencyKeys != null && dependencyKeys.Length > 0)
    AddKeyDependency(key, dependencyKeys);
    }

      

     
     
     
    标签: Cache
  • 相关阅读:
    Idea导出jar包运行报错:找不到主清单属性解决方法
    Java开发桌面程序学习(一)——JavaFx+Jfoenix初始以及搭建
    JavaFx出现错误Caused by: java.lang.NullPointerException: Location is required的解决方法
    IDEA maven设置配置
    oracle学习笔记(十九) 子程序——存储过程
    ASP.NET Core 指定环境发布(hosting environment)
    解决Visual Studio 2017隐藏“高级保存选项”命令
    【亲测可用,亦可配置同一平台的不同账号,例如阿里云的两个不同账号】Windows下Git多账号配置,同一电脑多个ssh-key的管理
    Xshell5 评估过期,需要采购,不能使用
    linux上mongodb的安装与卸载
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3334413.html
Copyright © 2020-2023  润新知