非常轻便,性能好,适合单机使用。
使用流程:1. 用 c := memorycache.New() new一个对象
2. 然后
c.Get(key interface{}, f …func(key, old interface{}) (v interface{}, t int64) ) interface{}
这个方法结合了 获取 和 设置 缓存的功能,你可能认为 卧槽这不按常理出牌啊。
这么设计是为了提升性能和易用性,你大可一试,你会发现,哎哟,可以哟。
key参数应该不用介绍了吧。
f …func(key, old interface{}) (v interface{}, t int64),
一个创建数据的函数,当没有缓存或缓存过期时,自动调用该函数生成新的缓存,old是传入旧的数据,你可以在它被销毁之前见最后一面,该函数应该返回将被缓存的数据和过期时间,0永不过期,单位秒。
3. 其他方法
c.Delete(key interface{})
这个方法用来删除缓存,很简单就不介绍了。
c.SetExpire(key interface{}, expire int64) bool
设置缓存时间
c.Each(f func(k, v interface{}))
遍历缓存
memorycache.GC()
清理过期的数据,需要手动调用,比如放到定时任务中
如果数据总量不多,建议懒得GC
package main
import (
"fmt"
"sync"
"time"
"wego/memorycache"
)
func main() {
// f 用于生成数据的函数
f := func(key,old interface{}) (interface{},int64) {
fmt.Println("如果多次显示这条信息,代表发生了 穿透 和 击穿")
return nil,0
}
// new 一个 缓存
c := memorycache.New()
// 开1000个协程测试应该够了
// 目前使用的是公司配的渣渣电脑(因为害怕崩溃到发抖o((⊙﹏⊙))o.)
now := time.Now()
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
// 获取缓存,如果不存在或过期就用 f() 创建
c.Get("key", f)
wg.Add(-1)
}()
}
wg.Wait()
// 消耗时间
fmt.Println(time.Since(now))
// 输出结果
//
// $ go run 1.go
// 如果多次显示这条信息,代表发生了 穿透 和 击穿
// 1.0001ms
//
// 分析:可以看到整个过程只消耗了 1ms 左右,所以应该没有发生雪崩,不然消耗时间应该 1s 以上
// 接下来测试过期
// 设置缓存,有效 4s
c.Get("a", func(key,old interface{}) (interface{},int64) {
return 111,4
})
// 3s 后获取
time.Sleep(3 * time.Second)
fmt.Println(c.Get("a", nil))
// 4s 后获取
time.Sleep(1 * time.Second)
fmt.Println(c.Get("a", nil))
// 输出结果
//
// $ go run 1.go
// 如果多次显示这条信息,代表发生了 穿透 和 击穿
// 0s
// 111
// <nil>
//
}