当前位置: 首页 > news >正文

KCache-go本地缓存,支持本地缓存过期、缓存过期自维护机制。

GitHub - kocor01/kcache: go 本地缓存解决方案,支持本地缓存过期、缓存过期自维护机制。

最近系统并发很高,单接口10W的 QPS,对 redis 压力很大,大量的热KEY导致 redis 分片CPU资源经常告警。计划用 go 本地缓存缓解 redis 的压力。

有多个系统需要使用本地缓存,写了 KCache 方便各个系统使用。

本地压测达到 100W QPS。

使用请参考 使用实例

创建KCache

  • 创建一个KCache, 默认本地缓存过期时间 5s

    kc := New()
    
  • 创建一个KCache, 自定义本地缓存过期时间

    kc := NewWithExp(2 * time.Second)
    

获取缓存

  • GET 获取缓存,函数不带参数,本地缓存过期时间为创建 KCache 时设置的全局过期时间。

      kc := New()d := kc.Get("myKey", GetData())
    

    GET 方法包含两个参数,第一个参数为缓存的key,第二个参数为获取缓存数据的函数。当缓存不存在时,会调用函数获取数据,并将数据缓存起来。 函数需符合 GetKcDatafunc 类型、返回值需符合 KcData 类型。

    type GetKcDatafunc func() KcDatatype KcData struct { interface{} error
    }
    

    示例:

    // 获取缓存数据
    func GetData() GetKcDatafunc {return func() KcData {// sleep 模拟从 Redis、DB 中获取数据time.Sleep(20 * time.Millisecond)d := map[string]string{"k1": "value1","k2": "value2",}return KcData{d: d, err: nil}}
    }
    
  • Get 获取缓存,函数带参数

    kc := New()
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.Get("myKey", GetDataV2("myKey", params))
    

    示例:

    // 获取缓存数据
    func GetDataV2(key string, params map[string]string) GetKcDatafunc {return func() KcData {// sleep 模拟从 Redis、DB 中获取数据,也可以先从 redis 获取数据, 如果获取不到,再从 DB 中获取。time.Sleep(20 * time.Millisecond)data := make(map[string]string)for k, v := range params {data[k+key] = v}return KcData{d: data, err: nil}}
    }
    
  • GetWithExp 获取缓存,自定义本地缓存时间

    kc := New() 
    exp := 2 * time.Second
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.GetWithExp("myKey", exp, GetDataV2("myKey", params))
    

GetKcDatafunc 实现

  • Kcache 中间函数(强烈推荐)

    通过 Kcache 中间函数调用原有的获取数据函数,该函数内部不含任何业务代码,减少业务代码与缓存代码的耦合。

    kc := New()
    exp := 2 * time.Second
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.GetWithExp("myKey", exp, GetDataKcache("myKey", params))
    
    // 获取缓存数据, Kcache 中间函数
    func GetDataKcache(key string, params map[string]string) GetKcDatafunc {return func() KcData {data, err := GetDataV2(key, params)return KcData{Data: data, Err: err}}
    }// 获取数据
    func GetDataV2(key string, params map[string]string) (map[string]string, error) {// sleep 模拟从 Redis、DB 中获取数据,也可以先从 redis 获取数据, 如果获取不到,再从 DB 中获取。time.Sleep(20 * time.Millisecond)data := make(map[string]string)for k, v := range params {data[k+key] = v}return data, nil
    }
    
  • 闭包函数(推荐)

    简单获取数据的业务逻辑可以使用闭包函数。

    kc := New()
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    key := "myKey"
    fc := func() KcData {// sleep 模拟从 Redis、DB 中获取数据,也可以先从 redis 获取数据, 如果获取不到,再从 DB 中获取。time.Sleep(20 * time.Millisecond)data := make(map[string]string)for k, v := range params {data[k+key] = v}return KcData{Data: data, Err: nil}
    }
    d := kc.Get(key, fc)
    
  • 业务混合

    kc := New()
    d := kc.Get("myKey", GetData())
    
    // 获取缓存数据
    func GetData() GetKcDatafunc {return func() KcData {// sleep 模拟从 Redis、DB 中获取数据time.Sleep(20 * time.Millisecond)d := map[string]string{"k1": "value1","k2": "value2",}return KcData{Data: d, Err: nil}}
    }
    

设置缓存

  • Set 设置缓存,本地缓存过期时间为创建 KCache 时设置的全局过期时间。

    正常情况下无需使用 Set 方法,因为 Get 方法会自动设置缓存。

    kc := New()
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.Set("myKey", params)
    
  • SetWithExp 设置缓存,自定义本地缓存时间。

    正常情况下无需使用 SetWithExp 方法,因为 Get 方法会自动设置缓存。

    kc := New()
    exp := 2 * time.Second
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.SetWithExp("myKey", params, exp)
    

删除缓存

  • Delete 删除本地缓存

    正常情况下无需使用 Delete 方法,因为有自动删除缓存机制。

    kc := New()
    params := map[string]string{"k1": "value1","k2": "value2",
    }
    d := kc.Delete("myKey")
    

单纯使用本地缓存

  • 不需要自维护缓存数据

  • 底层使用的 go-cache,go-cache下的所有方法都可以使用。

    kc := New()
    // SET
    kc.lc.Set("myKey", "myValue", 2*time.Second)
    // GET
    d, f := kc.lc.Get("myKey")
    // other
    ...

更多使用案列请参考 使用实例

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Chrome谷歌浏览器Console(控制台)显示文件名及行数
  • Open3D 计算点云的占地面积
  • HarmonyOS NEXT零基础入门到实战-第四部分
  • 速盾:cdn能防御ddos吗?
  • Codeforces Round 874 (Div. 3)(A~D题)
  • 掌握AJAX技术:从基础到实战
  • reduceByKey 函数详解
  • 1-如何挑选Android编译服务器
  • Git拉取国外远程嵌套代码
  • Kylin自定义函数全解:释放数据分析的无限潜能
  • 【Web】LitCTF 2024 题解(全)
  • JavaScript数据筛选和模糊搜索
  • Infuse Pro for Mac全能视频播放器
  • PySide(PyQt)的QPropertyAnimation(属性动画)的应用实践
  • vue elementui 在table里使用el-switch
  • python3.6+scrapy+mysql 爬虫实战
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【译】理解JavaScript:new 关键字
  • 11111111
  • HTML5新特性总结
  • Linux下的乱码问题
  • log4j2输出到kafka
  • NSTimer学习笔记
  • opencv python Meanshift 和 Camshift
  • ucore操作系统实验笔记 - 重新理解中断
  • 程序员该如何有效的找工作?
  • 关于Flux,Vuex,Redux的思考
  • 算法---两个栈实现一个队列
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 第二十章:异步和文件I/O.(二十三)
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • (¥1011)-(一千零一拾一元整)输出
  • (06)金属布线——为半导体注入生命的连接
  • (1)(1.13) SiK无线电高级配置(六)
  • (2)STM32单片机上位机
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (第61天)多租户架构(CDB/PDB)
  • (二)springcloud实战之config配置中心
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (佳作)两轮平衡小车(原理图、PCB、程序源码、BOM等)
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (南京观海微电子)——I3C协议介绍
  • (算法)区间调度问题
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (一)认识微服务
  • (已解决)什么是vue导航守卫
  • (原創) 物件導向與老子思想 (OO)
  • .net dataexcel winform控件 更新 日志
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET设计模式(8):适配器模式(Adapter Pattern)