mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-20 22:17:09 +08:00
cache-aside-pattern
This commit is contained in:
parent
71ed90c4d6
commit
5793e51cb0
File diff suppressed because one or more lines are too long
BIN
docs/database/Redis/images/缓存读写策略/cache-aside-read.png
Normal file
BIN
docs/database/Redis/images/缓存读写策略/cache-aside-read.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
File diff suppressed because one or more lines are too long
BIN
docs/database/Redis/images/缓存读写策略/cache-aside-write.png
Normal file
BIN
docs/database/Redis/images/缓存读写策略/cache-aside-write.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
@ -92,13 +92,62 @@ _那本地缓存的方案有哪些呢?且听 Guide 给你来说一说。_
|
||||
|
||||
#### 5.1. Cache Aside Pattern(旁路缓存模式)
|
||||
|
||||
1. 写:更新 DB,然后直接删除 cache 。
|
||||
2. 读:从 cache 中读取数据,读取到就直接返回,读取不到的话,就从 DB 中取数据返回,然后再把数据放到 cache 中。
|
||||
|
||||
Cache Aside Pattern 中服务端需要同时维系 DB 和 cache,并且是以 DB 的结果为准。另外,Cache Aside Pattern 有首次请求数据一定不在 cache 的问题,对于热点数据可以提前放入缓存中。
|
||||
|
||||
**Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。**
|
||||
|
||||
Cache Aside Pattern 中服务端需要同时维系 DB 和 cache,并且是以 DB 的结果为准。
|
||||
|
||||
下面我们来看一下这个策略模式下的缓存读写步骤。
|
||||
|
||||
**写** :
|
||||
|
||||
- 先更新 DB
|
||||
- 然后直接删除 cache 。
|
||||
|
||||
简单画了一张图帮助大家理解写的步骤。
|
||||
|
||||

|
||||
|
||||
**读** :
|
||||
|
||||
- 从 cache 中读取数据,读取到就直接返回
|
||||
- cache中读取不到的话,就从 DB 中读取数据返回
|
||||
- 再把数据放到 cache 中。
|
||||
|
||||
简单画了一张图帮助大家理解读的步骤。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
你仅仅了解了上面这些内容的话是远远不够的,我们还要搞懂其中的原理。
|
||||
|
||||
比如说面试官很可能会追问:“**在写数据的过程中,可以先删除缓存,后更新数据库么?**”
|
||||
|
||||
**答案:** 那肯定是不行的!因为这样可能会造成**数据库和缓存数据不一致**的问题。为什么呢?比如说请求1 先写数据A,请求2随后读数据A的话就很有可能产生数据不一致性的问题。这个过程可以简单描述为:
|
||||
|
||||
> 请求1先把缓存中的A数据删除 -> 请求2从数据库中读取数据->请求1再把数据库中的A数据更新。
|
||||
|
||||
当你这样回答之后,面试官可能会紧接着就追问:“**在写数据的过程中,先更新数据库,后删除缓存就没有问题了么?**”
|
||||
|
||||
**答案:** 理论上来说还是可能会出现数据不一致性的问题,不过概率非常小,因为缓存的写入速度是比数据库的写入速度快很多!
|
||||
|
||||
比如请求1先读数据 A,请求2随后写数据A,并且数据库A不在缓存中的话也有可能产生数据不一致性的问题。这个过程可以简单描述为:
|
||||
|
||||
> 请求1从DB读数据A->请求2写更新数据 A 到数据库并把删除缓存中的A数据->请求1将数据库A写入缓存。
|
||||
|
||||
现在我们再来分析一下 **Cache Aside Pattern 的缺陷**。
|
||||
|
||||
**缺陷1:首次请求数据一定不在 cache 的问题**
|
||||
|
||||
解决办法:可以将热点数据可以提前放入缓存中。
|
||||
|
||||
**缺陷2:写操作比较频繁的话导致缓存中的数据会被频繁被删除,这样会影响缓存命中率 。**
|
||||
|
||||
解决办法:
|
||||
|
||||
- 数据库和缓存数据强一致场景 :更新数据的时候同样更新缓存,不过我们需要加一个锁/分布式锁来保证更新缓存的时候不存在线程安全问题。
|
||||
- 可以短暂地允许数据库和缓存数据不一致的场景 :更新数据的时候同样更新缓存,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。
|
||||
|
||||
#### 5.2. Read/Write Through Pattern(读写穿透)
|
||||
|
||||
Read/Write Through 套路是:服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 DB,从而减轻了应用程序的职责。
|
||||
|
Loading…
x
Reference in New Issue
Block a user