一、介绍
bigcache是一个内存缓存系统,用于存储键值对数据。没有gc操作。使用的时候需要序列化(反)。
bigcache的源代码在 https://github.com/allegro/bigcache
几个特征,存储通过[]byte,没有过期时间。
二、安装
我们安装最新的v3版本
go get -u github.com/allegro/bigcache/v3
安装完成后,我们就可以在go语言中使用bigcache了。下面是一些简单的示例。
三、使用示例
func TestSetGet(t *testing.T) {
// new一个bigCache对象
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
// get获取一个无值的key
vNil, err := cache.Get("key")
t.Log(vNil, err) // [] Entry not found 值为空的[]字节slice
// set 存储数据
cache.Set("key", []byte("value"))
// get 获取数据
v, _ := cache.Get("key")
t.Log(v) // 输出 [118 97 108 117 101]
t.Log(string(v)) // 输出 value
}
我们看一下 Set和Get方法的源代码
// Set saves entry under the key
func (c *BigCache) Set(key string, entry []byte) error {
hashedKey := c.hash.Sum64(key)
shard := c.getShard(hashedKey)
return shard.set(key, hashedKey, entry)
}
// Get reads entry for the key.
// It returns an ErrEntryNotFound when
// no entry exists for the given key.
func (c *BigCache) Get(key string) ([]byte, error) {
hashedKey := c.hash.Sum64(key)
shard := c.getShard(hashedKey)
return shard.get(key, hashedKey)
}
在Set()方法,存储值为 []byte
字节slice类型,所以我们保存的时候,需要序列化数据成[]byte
。
而在Get()方法,获取的值为[]byte
,我们此时需要反序列化[]byte
成原来的类型。
3、1 string类型的 存储与获取以及修改
string类型可以用[]byte和类型,互相的方便转换。
func TestSetGet(t *testing.T) {
// new一个bigCache对象
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
// get获取一个无值的key
vNil, err := cache.Get("key")
t.Log(vNil, err) // [] Entry not found 值为空的[]字节slice
// set 存储数据
cache.Set("key", []byte("value"))
// get 获取数据
v, _ := cache.Get("key")
t.Log(v) // 输出 [118 97 108 117 101]
t.Log(string(v)) // 输出 value
}
3、2 非string类型的 存储与获取以及修改
非string类型,转成[]byte,比较复杂,在go内置的库中,唯有json库,提供了这样的方法。可以把非string的任意类型,转成[]byte,如下。
func Marshal(v any) ([]byte, error) // 序列化
func Unmarshal(data []byte, v any) error // 反序列化
在这里我们也使用json的序列化(反)方法,来和[]byte互转。
3、2、1 slice切片类型的存储与获取以及修改
// TestSetGetSlice slice类型
func TestSetGetSlice(t *testing.T) {
// new一个bigCache对象
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
// slice 存储数据
s := []string{"1", "2"}
bs, _ := json.Marshal(s)
cache.Set("s", bs)
// get获取值
bsv, _ := cache.Get("s")
var s2 []string = make([]string, 0)
_ = json.Unmarshal(bsv, &s2)
t.Log(s2)
// 修改数据,修改s2,查看是否会影响内存中的值
// 答案是不影响
s2 = append(s2, "3")
t.Log(s2)
var s3 []string = make([]string, 0)
_ = json.Unmarshal(bsv, &s3)
t.Log(s3)
}
3、2、2 struct结构体类型的存储与获取以及修改
// TestSetGetStruct 结构体指针
func TestSetGetStruct(t *testing.T) {
// new一个bigCache对象
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
// 结构体struct 存储数据
type st struct {
Value string
}
s := &st{
Value: "v1",
}
bs, _ := json.Marshal(s)
cache.Set("s", bs)
// get获取值
bsv, _ := cache.Get("s")
var s2 st
_ = json.Unmarshal(bsv, &s2)
t.Log(s2) // {v1}
// 修改数据,修改s2,查看是否会影响内存中的值
// 答案是不影响
s2.Value = "v2"
t.Log(s2) // {v2}
var s3 st
_ = json.Unmarshal(bsv, &s3)
t.Log(s3) // {v1}
}
结论是:bigcache可以安全使用,修改获取后的是,也不影响原来内存中的值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。