Go增加Redis缓存机制
约 588 字
预计阅读 2 分钟
Go增加Redis缓存机制方案
增加缓存机制
- 缓存基于redis,以数据集为单位组织存储。
- 根据查询条件序列化生成单独的key,查询数据作为内容,组成缓存的最小单元。
- 数据查询时先进行redis缓存查询,如果命中,直接取缓存内容返回,未命中则继续执行后续程序,从数据库中查询内容,查询成功后存入缓存,以待下次使用。
缓存模块提供方法
1
2
3
4
5
6
7
8
|
//存储缓存方法
func (c *Cache) HSet(ctx context.Context, datasetId int, key string, value interface{})
//获取缓存方法
func (c *Cache) HGet(ctx context.Context, datasetId int, key string) string
//删除缓存,以数据集为单位
func (c *Cache) Del(ctx context.Context, datasetId int)
|
缓存击穿与并发解决方案
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
|
import "sync"
type call struct {
wg sync.WaitGroup
val interface{}
err error
}
type Group struct {
mu sync.Mutex
m map[string]*call
}
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
g.mu.Lock()
if g.m == nil {
g.m = make(map[string]*call)
}
if c, ok := g.m[key]; ok {
g.mu.Unlock()
c.wg.Wait()
return c.val, c.err
}
c := new(call)
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()
c.val, c.err = fn()
c.wg.Done()
g.mu.Lock()
delete(g.m, key)
g.mu.Unlock()
return c.val, c.err
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import (
"testing"
)
func TestDo(t *testing.T) {
var g Group
v, err := g.Do("key", func() (interface{}, error) {
return "bar", nil
})
if v != "bar" || err != nil {
t.Errorf("Do v = %v, error = %v", v, err)
}
}
|