# 4.9 调用本地缓存
# 4.9.1 简介
pkg/cache/xfreecache 包是对freecache库进行二次封装,用于本地缓存并支持metric上报
frercache特性:
- 可存储数以百万计条目
- 零垃圾收集负荷
- 高并发而且线程安全的访问
- 纯 Go 语言实现
- 支持对象失效
- 近乎 LRU 的算法
- 严格限制内存使用
# 4.9.2 注意事项
- 缓存key的大小需要小于65535,否则无法存入到本地缓存中(The key is larger than 65535)
- 缓存value的大小需要小于缓存总容量的1/1024,否则无法存入到本地缓存中(The entry size need less than 1/1024 of cache size)
# 4.9.3 使用泛型的用法(推荐)
# 1 初始化实例
# 1) 配置规范
[jupiter.cache]
# 本地缓存总容量 默认256MB
# 缓存value的大小需要小于缓存总容量的1/1024,否则无法存入到本地缓存中
# 可支持单位: B或Btye、KB、MB、GB、TB (大小写均支持)
size = "256MB"
[jupiter.cache.student]
expire = "2m" # 本地缓存失效时间
disableMetric = false # 是否禁用metric上报 false 开启 ture 关闭 默认开启上报
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2) 初始化方式
import (
"github.com/douyu/jupiter/pkg/cache/xfreecache/v2"
)
type Student struct {
Age int
Name string
}
type Instance struct {
localCache *xfreecache.LocalCache[string, Student]
}
func NewInstance() *Instance {
return &Instance{
localCache: xfreecache.StdNew[string, Student]("student"),
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 若juno中无配置时,会初始化一个默认配置。默认配置详情:缓存容量:
256MB
(缓存value需要小于256KB) 失效时间:2分钟
是否开启metric上报:是
- 初始化多个配置时,内部只会初始化一个缓存容量为256MB的缓存实例。无需担心初始化多个实例后的缓存消耗
# 2 函数方法介绍
// GetAndSetCacheData 获取缓存后数据(内部已封装设置和获取本地缓存操作)【推荐使用】
// key 缓存key
// id 索引(无作用,会组装到key里面)
// fn 获取返回数据需要执行的方法
// value
// err fn返回的错误以及其他报错
func (c *cache[K, V]) GetAndSetCacheData(key string, id K, fn func() (V, error)) (value V, err error)
// GetCacheValue 获取缓存数据
// key 缓存key
// id 索引(无作用,会组装到key里面)
// value
func (c *cache[K, V]) GetCacheValue(key string, id K) (value V)
// SetCacheValue 设置缓存数据
// key 缓存key
// id 索引(无作用,会组装到key里面)
// fn 获取返回数据需要执行的方法
// err fn返回的错误以及其他报错
func (c *cache[K, V]) SetCacheValue(key string, id K, fn func() (V, error)) (err error)
// GetAndSetCacheMap 获取缓存后数据 map形式 【推荐使用】
// key 缓存key
// ids 返回map中的key集合
// fn 获取返回数据需要执行的方法
// value
// err fn返回的错误以及其他报错
func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (v map[K]V, err error)
// GetCacheMap 获取缓存数据 map形式
// key 缓存key
// ids 返回map中的key集合
// value
func (c *cache[K, V]) GetCacheMap(key string, ids []K) (v map[K]V)
// SetCacheMap 设置缓存数据 map形式
// key 缓存key
// ids 返回map中的key集合
// fn 获取返回数据需要执行的方法
// err fn返回的错误以及其他报错
func (c *cache[K, V]) SetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (err error)
// SetCacheData 设置本地缓存
// key 缓存key
// data 缓存value,传入序列化后的字节数组
func SetCacheData(key string, data []byte)
// GetCacheData 获取本地缓存
// key 缓存key
// data 缓存value
// err error
func GetCacheData(key string) (data []byte, err error)
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
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
# 3 实际案例
配置项
[jupiter.cache.bwlist]
expire = "1m" # 本地缓存失效时间
1
2
2
代码
package bwlist
import (
"context"
"github.com/douyu/jupiter/pkg/cache/xfreecache/v2"
)
type Instance struct {
localCache *xfreecache.LocalCache[int32, []int32]
}
func NewInstance() *Instance {
return &Instance{
localCache: xfreecache.StdNew[int32, []int32]("bwlist"),
}
}
// GetBWListCached 获取单个白名单配置-带1min本地缓存
// id 白名单配置id
func (i *Instance) GetBWListCached(ctx context.Context, id int32) (res []int32, err error) {
res, err = i.localCache.GetAndSetCacheData("bwlist.GetBWList", id, func() ([]int32, error) {
data, innerErr := i.GetBWList(ctx, id)
return data, innerErr
})
return
}
// BatchGetBWListCached 批量获取白名单配置-带1min本地缓存
// ids 多个白名单配置id
func (i *Instance) BatchGetBWListCached(ctx context.Context, ids []int32) (res map[int32][]int32, err error) {
res, err = i.localCache.GetAndSetCacheMap("bwlist.GetBWList", ids, func(innerIds []int32) (map[int32][]int32, error) {
data, innerErr := i.BatchGetBWList(ctx, innerIds)
return data, innerErr
})
return
}
// GetBWList 获取单个白名单配置-不带缓存
// id 白名单配置id
func (i *Instance) GetBWList(ctx context.Context, id int32) (res []int32, err error) {
// TODO 可以根据实际业务具体实现方法
return
}
// BatchGetBWList 批量获取白名单配置-不带缓存
// ids 多个白名单配置id
func (i *Instance) BatchGetBWList(ctx context.Context, id []int32) (res map[int32][]int32, err error) {
// TODO 可以根据实际业务具体实现方法
return
}
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
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
# 4.9.4 不使用泛型的用法(返回字节数组,需要自己实现序列化)
# 1 初始化实例
# 1) 使用默认的初始化方式
- 初始化方式
type Instance struct {
localCache *xfreecache.LocalCache
}
func NewInstance() *Instance {
return &Instance{
localCache: xfreecache.DefaultConfig().Build(),
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 默认配置详情:缓存容量:
256MB
(缓存value需要小于256KB) 失效时间:2分钟
是否开启metric上报:是
type Config struct {
Size Size // 缓存容量,最小512*1024 【必填】
Expire time.Duration // 失效时间 【必填】
DisableMetric bool // metric上报 false 开启 ture 关闭【选填,默认开启】
Name string // 本地缓存名称,用于日志标识&metric上报【选填】
}
// DefaultConfig 返回默认配置
func DefaultConfig() Config {
return Config{
Size: 256 * MB,
Expire: 2 * time.Minute,
DisableMetric: false,
Name: fmt.Sprintf("cache-%d", time.Now().UnixNano()),
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2) 自定义初始化方式
func NewInstance() *Instance {
return &Instance{
localCache: xfreecache.Config{
Size: 128 * xfreecache.MB,
Expire: 2 * time.Minute,
DisableMetric: false,
Name: "bwList",
}.Build(),
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2 函数方法介绍
// GetAndSetCacheData 获取缓存后数据(内部已封装设置和获取本地缓存操作)【推荐使用】
// key 缓存key
// fn 获取返回数据需要执行的方法
// err fn返回的错误以及其他报错
func GetAndSetCacheData(key string, fn func() ([]byte, error)) (v []byte, err error)
// SetCacheData 设置本地缓存
// key 缓存key
// data 缓存value,传入序列化后的字节数组
func SetCacheData(key string, data []byte)
// GetCacheData 获取本地缓存
// key 缓存key
// data 缓存value
// err error
func GetCacheData(key string) (data []byte, err error)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3 实际案例
package bwlist
import (
"context"
"encoding/json"
"fmt"
"time"
"git.dz11.com/vega/minerva/log"
"github.com/douyu/jupiter/pkg/cache/xfreecache"
"go.uber.org/zap"
)
type Instance struct {
localCache *xfreecache.LocalCache
}
func NewInstance() *Instance {
return &Instance{
localCache: xfreecache.Config{
Size: 128 * xfreecache.MB,
Expire: 2 * time.Minute,
DisableMetric: false,
Name: "bwList",
}.Build(),
}
}
type GetBWListRequest struct {
// 黑白名单ID
Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
// 1 白名单 2 黑名单
LimitType int32 `protobuf:"varint,3,opt,name=limit_type,json=limitType" json:"limit_type,omitempty"`
}
func (i *Instance) GetBWListCached(ctx context.Context, req *GetBWListRequest) (res []int32, err error) {
cacheKey := fmt.Sprintf("bwlist.GetBWList:%d:%d", req.Id, req.LimitType)
data, err := i.localCache.GetAndSetCacheData(cacheKey, func() ([]byte, error) {
data, innerErr := i.GetBWList(ctx, req)
ret, _ := json.Marshal(data)
return ret, innerErr
})
err = json.Unmarshal(data, &res)
if err != nil {
log.L(ctx).Error("bwlist GetBWListCached Unmarshal", zap.Any("req", req), zap.Error(err))
}
return
}
func (i *Instance) GetBWList(ctx context.Context, req *GetBWListRequest) (res []int32, err error) {
// 可以根据实际业务具体实现方法
res = []int32{123456}
return
}
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
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
# 4.9.5 juno监控
← 4.8 调用Trace 5.1 概述 →