redis缓存

缓存的设计

什么是缓存

缓存,是一种存储数据的组件,它的作用是让对数据的请求更快地返回。

缓存存在的意义

提升访问速度,提升性能,从而能够抗住更高的并发 。因为在系统中大部分的系统瓶颈出现在数据库中,所以我们可以减少数据库的访问来提高系统的并发量。

缓存中存在的问题

1.缓存一致性问题

2.缓存是适用于读多写少的场景

缓存的设计

1.主动覆盖更新策略

获取数据只依赖缓存, 不依赖db, db数据更新时, 会更新缓存数据.

读策略:

  • 缓存读取数据, 无论是否命中, 均返回, 不会穿透到db

写策略:

  • 业务事件/任务, 监听业务数据变化、主动更新缓存数据

优点:

  • 适用于大量并发读的场景, 利用缓存快速读取特性, 提供高性能.

缺点:

  • 存在数据不一致问题, 业务db数据已更新, 但缓存数据未更新
  • 高可用性问题, 因为客户端读只和缓存交互, 不会穿透到db, 缓存服务出问题,等于服务不可用.
2.过期更新策略

读策略:

  • 缓存读取数据、未命中 → 查询数据库 → 更新缓存数据

写策略:

  • 业务直接操作db, 不更新缓存
  • 缓存数据失效后, 读操作会加载db、主动更新缓存数据.

优点

  • 实现简单

缺点

  • 存在数据不一致问题, 业务db数据已更新,但缓存数据未过期, 无法更新缓存数据.

  • 使用时: 需要根据业务场景设置缓存过期时间.

3、同步更新策略:

同步更新缓存和数据库db

image-20211230234323663

  • 缺陷: 存在数据不一致问题.
  • 过程: 请求1发起更新db → 请求2发起更新db → 请求2更新缓存 → 请求1更新缓存
  • 原因: db、缓存两个动作独立,线程并发写入顺序不同,造成数据不一致.

image-20211230234339688

解决: 我们可以在更新数据时不更新缓存,而是删除缓存中的数据,在读取数据时,发现缓存中没了数据之后,再从数据库中读取数据,更新到缓存中。

​ 该解决方案就是Cache Aside旁路缓存策略

4、Cache Aside旁路缓存策略

image-20211230234352905

读策略:

  1. 从缓存中读取数据
  2. 如果缓存命中,则直接返回数据;
  3. 如果缓存不命中,则从数据库中查询数据;
  4. 查询到数据后,将数据写入到缓存中

写策略:

  1. 更新数据库db
  2. 删除缓存记录

先删除缓存,后更新数据库行不行 ?

答: 不行, 存在数据不一致问题

ps: 请求 1 先把 cache 中的数据删除 -> 请求 2 从 DB 中读取数据→ 请求 1 再把 DB 中的数据更新

image-20211230234408786

Cache Aside旁路缓存策略不足 ?

理论上还是有缺陷

1、当缓存未命中时, 请求 1 从 DB 读数据 A → 请求 2 写更新数据 A 到数据库并把删除 cache 中的 A 数据 → 请求 1 将数据 A 写入 cache

image-20211230234418720

不过这种问题出现的几率并不高,原因是缓存的写入通常远远快于数据库的写入,所以在实际中很难出现,请求2已经更新了数据库并且清空了缓存,请求1才更新完缓存的情况

2、写入比较频繁时,缓存中的数据会被频繁地清理,这样会对缓存的命中率有一些影响

如果对缓存命中率有高的要求, 可以

  • 采用同步更新策略 (更新数据时也更新缓存), 只是在更新操作先加一个分布式锁,解决并发问题导致的数据不一致问题, 当然这么做影响写入性能.
  • 采用同步更新策略 (更新数据时也更新缓存), 只是给缓存加一个较短的过期时间,允许短暂的缓存数据不一致问题, 减少业务影响.
5、Read/Write Through读写穿透策略

用户只与缓存打交道,缓存在和数据库通信 ,写入or读取.

Read/Write Through 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中

读策略:

  1. 先查询缓存中数据是否存在
  2. 如果存在则直接返回
  3. 如果不存在,则由缓存组件负责从数据库中同步加载数据

写策略:

  1. 先查询要写入的数据在缓存中是否已经存在
  2. 如果已经存在,则更新缓存中的数据,并且由缓存组件同步更新到数据库中
  3. 如果缓存中数据不存在,直接同步更新数据库

image-20211230234436465

Read/Write Through 策略缺陷:

1、极端情况仍有问题:

  • 请求1写数据缓存、未命中 → 请求2读数据、缓存未命中 → 请求2 db查询,更新缓存 → 请求1完成数据库db更新操作
    此时缓存中数据,不是请求1最新数据
  • 这种case极少出现, 正常来说请求A的数据库写入操作, 不会慢于请求2的数据库查询操作

2、数据可靠性缺陷, 先写入缓存,在从同步缓存到db, 存在业务重要数据不能落db风险

3、Read/Write Through较少使用

  • 因为没有现成的缓存同步db组件 ,例如redis 无组件直接提供cache到db的同步功能, 需要自行开发.
  • 重要数据需要先落db, cache到db存在数据丢失风险
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值