场景
用户访问某个资源,比如某个key,返回value。 当后端数据库较慢的时候(如mysql),就需要在前面加一个缓存(如 redis)。
请求 -》 服务 -》 缓存 -》 数据库
这时候,一般的方案是:
- 检查缓存是否存在
- 如果缓存命中,则直接返回
- 如果缓存未命中,则从数据库取数据
- 设置进缓存,并设置expire
何为lazy 缓存
本文称为lazy缓存,是一种方案,属于工程经验
缓存过期不删,而是触发更新,如果更新失败,则直接返回缓存内容
当然,这里可以将缓存过期的情况,使用异步更新缓存。而直接返回旧数据
可供参考,希望有所帮助
如何工作的呢
- 检查缓存是否存在
- 如果命中,则直接返回
- 如果未命中,则从数据库数取数据及修改时间
- 设置将value 和 value修改时间 存进缓存
- 整个缓存(redis)设置最大使用内存,并使用lru 模式清除数据
伪代码
data,err:= redis.Get(key)
//命中缓存,并且未过期
if err==nil && !isExpire(data) {
return data.value
}
//从数据库取数据
dbData,dbErr := mysql.Get(key)
if dbErr==nil{
//更新缓存,返回数据
redis.Set(key,dbData.value)
return dbData.value,nil
}
//如果数据库出错,则返回缓存数据(即使过期)
if err==nil{
return data.value,nil
}
return nil,dbErr
好处
唯有缓存未命中,并且数据库出错,才会返回错误
当数据库不稳定时:
方案1:
- redis 缓存命中,成功
- redis 缓存过期,失败
- redis 缓存不命中,失败
lazy缓存:
- redis 缓存命中,成功
- redis 缓存过期,成功
- redis 缓存不命中,失败
优化了,缓存过期,缓存击穿到数据库,而数据库失败时,仍然能成功
提高了服务的容错性