lazy缓存策略

场景

用户访问某个资源,比如某个key,返回value。 当后端数据库较慢的时候(如mysql),就需要在前面加一个缓存(如 redis)。

请求 -》 服务 -》 缓存 -》 数据库

这时候,一般的方案是:

  1. 检查缓存是否存在
  2. 如果缓存命中,则直接返回
  3. 如果缓存未命中,则从数据库取数据
  4. 设置进缓存,并设置expire

何为lazy 缓存

本文称为lazy缓存,是一种方案,属于工程经验

缓存过期不删,而是触发更新,如果更新失败,则直接返回缓存内容

当然,这里可以将缓存过期的情况,使用异步更新缓存。而直接返回旧数据

可供参考,希望有所帮助

如何工作的呢

  1. 检查缓存是否存在
  2. 如果命中,则直接返回
  3. 如果未命中,则从数据库数取数据及修改时间
  4. 设置将value 和 value修改时间 存进缓存
  5. 整个缓存(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:

  1. redis 缓存命中,成功
  2. redis 缓存过期,失败
  3. redis 缓存不命中,失败

lazy缓存:

  1. redis 缓存命中,成功
  2. redis 缓存过期,成功
  3. redis 缓存不命中,失败

优化了,缓存过期,缓存击穿到数据库,而数据库失败时,仍然能成功

提高了服务的容错性

humboldt Written by:

humboldt 的趣味程序园