缓存策略

缓存策略

缓存一致性

缓存预热

大促对于商品来说就是一年中最高峰的访问量,提前做好数据预热时保证双 11 等大促最关键的提前预案,如何确保提前预热的数据是"有效"的是预热质量的标志。对于商品中心来说,数据未命中主要会出现以下几种情况:   *商品数据不全,比如上述 spu、多语言信息、关联关系等   *tair 容量不足导致数据逐出   *各单元数据不一致,DRC 同步延迟   *数据不存在,导致请求直接打穿到 DB

所以,数据预热除了要保证数据数据本身的质量外,还需要提前预估、检查基础设施的稳定性。但对于数据本身来说: 第一步是收集数据: 1.获取大促前购物车、收藏夹 top5000w 数据;2.获取含有大促商品标的商品;3.其他预热商品,服务商品、零售通商品等业务方要求预热数据 第二步是校验数据:   大致的逻辑比较简单,通过预热平台引擎发起预热请求到 server 端,put 数据到 tair 中,然后模拟一次客户端调用,看是否能从 tair 中查询出数据,如果 tair 命中失败,检查是什么原因导致,同时统计模拟调用的命中率来呈现预热质量:

缓存设计

查询

更新 / 删除

DB 和缓存一致性

答:当修改了数据库后,有没有及时修改缓存。这种问题,以前有过实践,修改数据库成功,而修改缓存失败的情况,最主要就是缓存服务器挂了。而因为网络问题引起的没有及时更新,可以通过重试机制来解决。而缓存服务器挂了,请求首先自然也就无法到达,从而直接访问到数据库。那么我们在修改数据库后,无法修改缓存,这时候可以将这条数据放到数据库中,同时启动一个异步任务定时去检测缓存服务器是否连接成功,一旦连接成功则从数据库中按顺序取出修改数据,依次进行缓存最新值的修改。

缓存问题

缓存穿透

我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查 询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询 DB,这样缓存就失去了意义,在流量大时,可能 DB 就挂掉了。要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。

有一个比较巧妙的作法是,可以将这个不存在的 key 预先设定一个值。

比如,“key”, “&&”。

在返回这个 && 值的时候,我们的应用就可以认为这是不存在的 key,那我们的应用就可以决定是否继续等待继续访问,还是放弃掉这次操作。如果继续等待访问,过一个时间轮询点后,再次请求这个 key,如果取到的值不再是 &&,则可以认为这时候 key 有值了,从而避免了透传到数据库,从而把大量的类似请求挡在了缓存之中。

缓存并发

有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询 DB,同时设置缓存的情况,如果并发确实很大,这也可能造成 DB 压力过大,还有缓存频繁更新的问题。

我现在的想法是对缓存查询加锁,如果 KEY 不存在,就加锁,然后查 DB 入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入 DB 查询。

这种情况和刚才说的预先设定值问题有些类似,只不过利用锁的方式,会造成部分请求等待。

缓存失效

引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置 1 分钟啊,5 分钟这些,并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到 DB,DB 可能会压力过重。

那如何解决这些问题呢?

其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

下一页