网站建设中长出现的问题,番禺网站排名优化公司,企业做网站400电话作用,做网站带来的好处前言1. 什么是缓存击穿?2. 如何解决缓存击穿?怎么做?方案1: 定时刷新方案2: 自动续期方案3: 定时续期 如何选? 前言
当我们使用redis做缓存的时候,查询流程一般是先查询redis,如果redis未命中,再查询MySQL,将MySQL查询的数据同步到redis(回源),最后返回数据
流程图 为什… 前言1. 什么是缓存击穿?2. 如何解决缓存击穿?怎么做?方案1: 定时刷新方案2: 自动续期方案3: 定时续期 如何选? 前言
当我们使用redis做缓存的时候,查询流程一般是先查询redis,如果redis未命中,再查询MySQL,将MySQL查询的数据同步到redis(回源),最后返回数据
流程图 为什么使用 redis 作为缓存: 减少 DB 层 重复数据查询 的压力
redis 有 10 万QPSDB 只有几万(MySQL 1 万 QPS)
1. 什么是缓存击穿?
热 key 失效,当一个访问量特别高的一行数据在 redis 中失效,所有的请求全部打到 DB 层,可能直接将 DB 打爆
2. 如何解决缓存击穿?
两个方向:
热 key 不失效当热 key 失效(状态),同时只放一个请求去回源更新redis,其他请求(等待回源完成再取 redis 的数据或者返回空)
怎么做?
方案1: 定时刷新
每行数据除了数据本身以外储存一个更新标记,并且更新标记的过期时间小于数据的过期时间 case: 数据过期时间 10 分钟,数据的更新标记的过期时间 10 秒每次查询数据先检查更新标记是否存在(使用 redis 的 SET NX PX 命令),写失败意味着不需要更新,写成功意味着需要更新.判断第二步的执行结果: 成功(回源查询 DB 数据并更新到 redis,同时重置过期时间);失败(直接取 redis 的数据,如果取 redis 的数据也失败,则返回空(只放一个请求回源更新,其他等待回源完成再取 redis 的数据或者返回空))
总结: 热数据(不断访问)会根据更新标记自动的刷新数据,而不会过期(热数据永不过期)
方案2: 自动续期
使用 lua 脚本
先查询数据如果命中,重置数据的过期时间,并返回数据如果未命中: 设置一个空值(当 redis 没有数据,只允许一个请求回源),并回源 DB 层查询并更新到redis
总结: 使用 lua 脚本在命中redis 数据的时候就自动对数据的过期时间进行续期,实现热key 的过期 但是此方案不会自动更新数据,需要有其他的更新数据的逻辑(可参考redis 与 DB 的数据一致性)支持
方案3: 定时续期
对每行数据单独储存一个续期标记每次查询数据是先检查更新标记(SET NX PX) 如果成功 如果数据存在redis,重置过期时间;不存在设置一个空值并回源 DB 层查询更新(只放行一个请求回源更新) 如果失败(直接获取数据)
总结: 使用续期标记实现热数据的定时续期,实现热 key 的不过期 但是此方案不会自动更新数据,需要有其他的更新数据的逻辑(可参考redis 与 DB 的数据一致性)支持
如何选? 方案 1: 定时刷新 a. 天然包含数据一致性(每 更新标记的过期时间(10s) 会自动刷新数据) b. 足够的简单可靠 c. 如果项目对一致性要求不高的情况下可以选用 方案 2: 自动续期 a. 单个的逻辑很简单,并且是独立(与一致性)运行的,可自由搭配一致性策略 b. 如果项目对数据一致性有特殊要求,或者已经实现了一致性策略,可以选用 方案 3: 定时续期 a. 单个的逻辑较为复杂(对比方案 2), 并且是独立(与一致性)运行的,可自由搭配一致性策略 b. 如果项目对数据一致性有特殊要求,或者已经实现了一致性策略,可以选用方案 2