一:Redis 单线程时代性能很快的原因
- 基于内存操作:所有Redis的数据都存在内存中,因此所有的运算都是内存级别的,所以他的性能高
- 数据结构简单:Redis的数据结构的查找和操作时间大部分复杂度都是O(1),性能高
- 多路复用和非阻塞IO:Redis使用I/O多路复用来监听多个socket连接客户端,这样可以使用一个线程来处理多个请求,减少线程切换带来额开销,同时也避免了I/O阻塞操作
- 避免上下文切换:因为是单线程模型,这就省去了多线程切换带来的时间和性能上的消耗
二:为什么Redis6/7引入了多线程?
对于Redis 主要的性能瓶颈是内存或者网络带宽 而并非CPU,如果能采用多线程并行处理网络操作,就可以大大的提升性能。多线程还可以充分利用 CPU 的多核优势。Redis 只是将 I/O 读写变成了多线程,而命令的执行依旧是由主线程串行执行的
三:什么是热Key问题,如何解决热key问题?
如果在同一个时间点上,Redis中的同一个key被大量访问,就会导致流量过于集中,使得很多物理资源无法支撑,如网络带宽、物理存储空间、数据库连接等。
四:什么是大Key问题,如何解决?
- 什么是大Key:Redis中存储了大量数据的Key,不要误以为大 key只是表示Key的值很大,他还包括这个Key对应的value占用空间很多的情况
- 多大算大Key以及它的危害?
string 是value,最大512MB但是 >= 10KB 就是bigkey
list、hash、set和zset,含有的成员数量超过5000就是bigkey - 如何解决大Key问题
五:什么情况下会出现数据库和缓存不一致的问题?
- 在非并发的场景中:
因为缓存的操作和数据库的操作是存在一定的时间差的,而且这两个操作是没办法保证原子性的,也就是说,有可能一个操作成功,一个操作失败的。所以,这必然会存在不一致的情况。 - 在并发的场景中:
(1)如果两个线程,同时进行先写数据库,后更新缓存的操作,就可能会出现不一致
(2)如果两个线程,同时进行先更新缓存,后写数据库的操作,也可能会出现不一致
(3)读写并发,假如一个读线程,在读缓存的时候没查到值,他就会去数据库中查询,但是如果查询到结果之后,更新缓存之前,数据库被更新了,但是这个读线程是完全不知道的,那么缓存会重新用一个”旧值”覆盖掉。
六:如何解决Redis和数据库的一致性问题?
七:为什么需要延迟双删,两次删除的原因是什么?
所谓延迟双删,其实是:1、先删除缓存 2、更新数据库 3、删除缓存
第一次删除缓存的原因:为了避免两个操作无法作为一个原子操作而导致的不一致问题,我们选择先删除缓存,再更新数据库。
第二次删除缓存的原因:第一步先把缓存给清了,缓存中的数据被读线程写进去脏数据,那么就需要写线程第二次删除了
八:Redis之缓存预热 + 缓存雪崩 + 缓存击穿 + 缓存穿透
缓存雪崩
- 什么是缓存雪崩?
缓存雪崩就是瞬间过期数据量太大,导致对数据库服务器造成压力。 - 解决方案
(1)redis 中 key 设置为永不过期 or 过期时间错开
缓存穿透 - 什么是缓存穿透?
缓存穿透 就是请求去查询一条数据,先查redis,redis里面没有,再查mysql,mysql里面无,都查询不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增 - 解决方案
(1) 空对象缓存或者缺省值
(2) 布隆过滤器
缓存击穿 - 什么是缓存击穿?
缓存击穿就是大量请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去,也就是热点key突然都失效了,MySQL承受高并发量 - 解决方案
(1)差异失效时间,对于访问频繁的热点key,干脆就不设置过期时间