缓存就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。
为什么要使用Redis缓存呢?因为普通的基于的磁盘的数据库的IO速度相较于业务需要来说过慢,因此可以将Redis(基于内存的数据库)作为缓存中间件,将数据库中的频繁访问的数据存入到Redis中,提升数据库的访问速度,满足业务需求。
使用Redis缓存可以 降低后端负载,提高读写效率,降低访问时间。
使用Redis来做缓存,一般来讲都如下图所示:
当客户端有数据请求之后,首先会去访问Redis,如果Redis中存在,则直接返回,如果不存在则请求数据库,数据将返回的数据写入Redis,方便下次访问,并且将数据返回给客户端。
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,不断发起这样的请求,给数据库带来巨大压力。
解决方法:
1.缓存空对象
对于不存在的数据也在Redis建立缓存,值为空,并设置一个较短的TTL时间。
优点:实现简单,维护方便;
缺点:额外的内存消耗;会存在短期的数据不一致的问题。
2.布隆过滤
利用布隆过滤算法,在请求进入Redis之前先判断是否存在,如果不存在则直接拒绝请求。
优点:内存占用少。
缺点:实现复杂;存在误判的可能性。
3.其他方式
在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。我们可以根据描述的问题寻找解决方法。
解决方法:
缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。
解决方法:
1.互斥锁
因为当热点key突然过期时,同时会有多个请求同时访问数据库,带给数据库巨大冲击,因此只需要让一个请求去访问数据库,并重建缓存,其他请求在缓存重建之后通过访问缓存即可。这可以通过添加互斥锁的方式实现。即给缓存重建过程加锁,确保重建过程只有一个线程执行,其它线程等待。
优点:实现简单;没有额外内存消耗;一致性好。
缺点:等待导致性能下降;有死锁风险。
2.设置热点key永不过期,即设置逻辑过期时间。
热点key缓存永不过期,而是**设置一个逻辑过期时间,查询到数据时通过对逻辑过期时间判断,来决定是否需要重建缓存。**重建缓存也通过互斥锁保证单线程执行。重建缓存利用独立线程异步执行。其它线程无需等待,直接查询到的旧数据即可。
优点:线程无需等待,性能较好。
缺点:不保证一致性(弱一致性);有额外内存消耗;实现复杂。