目录

一、缓存

1、概念

2、作用

3、缺点

二、缓存模型

三、缓存的更新

1、更新策略

2、主动更新的三种模式

1.cache aside pattern

2.read/write through pattern

3.write behind caching pattern

3、线程安全问题

1.缓存删除还是更新缓存

2.先删除缓存后操作数据库

3.先操作数据库后删除缓存

4.如何保证缓存与数据库操作同时成功或失败

4、最佳选择



一、缓存

1、概念

缓存是数据交换的缓冲区,是数据存储的临时地方,相对来说他的读写性能比较高

2、作用

在web开发中缓存的引入会降低服务器的负载,提高读写效率降低响应时间

3、缺点

使用缓存会存在数据不一致性等问题,导致代码的维护成本变高。

如果在缓存集群的环境下,缓存的使用会消耗更多的人力资源

二、缓存模型

当客户端发送获取数据的请求时,我们先从redis中查询缓存,如果命中也就是缓存中存在数据,直接返回数据,如果缓存未命中,就需要去查询数据库然后将数据作为缓存写入redis

三、缓存的更新

1、更新策略

当数据库被修改,而客户端查询时查询到缓存里更新前的数据,为了解决这一问题有以下几种策略

内存淘汰超时删除主动更新
说明无需维护,利用redis本身的机制,当内存不足时自动淘汰部分数据,下次查询时更新缓存给缓存的数据加TTL即超时时间,到期后自动删除,下次查询时更新缓存在实现业务逻辑时,查询数据库的同时去更新缓存
一致性
维护成本

2、主动更新的三种模式

1.cache aside pattern

缓存调用者在操作数据库时的同时去更新缓存

2.read/write through pattern

将缓存与数据库作为一个整体的服务,由该服务来维护一致性。调用者只需要调用即可不需要去关心数据一致性问题

3.write behind caching pattern

调用者只需操作缓存,由其他线程异步的去将缓存的数据持久化到数据库,,以此来保证数据的一致性

3、线程安全问题

1.缓存删除还是更新缓存

上述三种模式,方案一虽然需要开发人员自己编码但是可控性比较高。那么我们在更新数据库的时候是将缓存删除还是更新缓存呢?

如果对数据库做了上百次操作,则需要去更新上百次缓存,但是却没有请求来查询,则上百次的更新缓存相当于是无效操作。而如果删除缓存,则查询请求来的时候就会查询数据库并更新缓存。那么我们选择了删除。

2.先删除缓存后操作数据库

此时又有一个问题,我们是先选择删除缓存后操作数据库呢,还是先操作数据库然后删除缓存呢?

先删除缓存后操作数据库,当线程1刚删除缓存时,线程2此时来查询,发现缓存没有,于是查询数据库,此时线程1还没有来得及去更新数据库,于是线程2获取到旧的数据返回并写入缓存,此时线程1更新完数据库。执行完毕时,缓存里的值是旧的,而数据库里确实跟新了的,就会存在线程安全的问题。

3.先操作数据库后删除缓存

先操作数据库后删除缓存,假设缓存由于某种原因失效了,线程1来查询时缓存未命中于是去查询数据库数据,此时线程2再去更新数据,并将缓存删除,此时线程1执行将读取到的旧数据写入缓存,缓存值与数据库不一致存在线程安全问题。

但是后者是在假定缓存失效的情景下,相比而言前者的线程安全问题更严重

4.如何保证缓存与数据库操作同时成功或失败

最后我们如何保证缓存与数据库操作同时成功或失败呢?

在单体系统里,我们可以将这两个操作放在一个事务里来保证,如果在分布式系统下则可以通过TCC等分布式事务来保证

4、最佳选择

如果对数据的一致性需求低,则可以使用默认的内存淘汰机制,对于一致性高的需求则使用主动更新的策略,并以超时删除作为兜底的方案