使用读写锁避免缓存穿透问题
var rwMu = sync.RWMutex{}
func GetForumById(id string) (result interface{}) {
rwMu.RLock()
result, err := cache.Get(id)
rwMu.RUnlock()
if err != nil {
log.Println("cache expired")
rwMu.Lock()
result, err = cache.Get(keyWord)
if err == nil {
log.Println("already be cached, return directly")
rwMu.Unlock()
return
}
log.Println("get data from mongodb")
data = mongodb.GetForumById(id))
cache.Set(id, data, 1)
rwMu.Unlock()
log.Println("data cached")
result, _ = cache.Get(id))
return
}
return
}
缓存穿透应该指的是,当多个请求同时请求同一个资源时,该资源未命中缓存,需要从数据库中获取。如果不使用锁,就会导致同时有多个数据库请求获取同一个资源,而这些请求是重复的,对数据库的重复请求是不需要的,且会对数据库造成极大的压力。图1
在使用锁之后,可以阻止对数据库的重复请求,减小数据库的压力。图2
用图来表示
黑色长条:web服务器
红色长条:缓存
橘色椭圆:数据库
图1. 缓存穿透,数据库压力增加
图2. 使用锁之后,数据库的压力减小
网友评论