Java八股文 ----Redis篇

问题大纲

Java八股文 ----Redis篇_第1张图片

Java八股文 ----Redis篇_第2张图片

缓存穿透

Java八股文 ----Redis篇_第3张图片

原因:入侵者大量查询不存在的数据  使得Redis不断去访问数据库  然而Redis也无法缓存,就导致每次都会查询数据库...数据库的并发度不高   就会宕机

解决办法

布隆过滤器:作用:拦截不存在的数据

Java八股文 ----Redis篇_第4张图片

布隆过滤器 原理:把数据的id通过多次哈希计算标记数组,新来个数据就计算哈希,看是否能验证标记,但是会有以下的误判情况

Java八股文 ----Redis篇_第5张图片

缓存击穿

某一个key设置了过期时间,当key过期的时候,恰好对这个key有大量的并发请求,导致所有的请求都落到数据库上  这些请求可能会瞬间把DB压垮

解决方案

互斥锁
Java八股文 ----Redis篇_第6张图片逻辑过期:数据不一定完全准确,但性能方面很优

Java八股文 ----Redis篇_第7张图片

Java八股文 ----Redis篇_第8张图片

缓存雪崩 

Java八股文 ----Redis篇_第9张图片

统一时段内大量的缓存key同时失效或者Redis服务

Java八股文 ----Redis篇_第10张图片

Java八股文 ----Redis篇_第11张图片Java八股文 ----Redis篇_第12张图片

双写一致性

有两种考察情况:

一种是要求实时性很高的

一种是允许延时一致(即延时以后再数据一致,不严格要求)

Java八股文 ----Redis篇_第13张图片

延迟双删---延时一致方案

有缺陷,但是面试爱问,如果只删除一次缓存,那么无论什么顺序都有可能脏读

而且,其实三步清除缓存也仍然有概率脏读

Java八股文 ----Redis篇_第14张图片

MQ很适用于延时一致的业务,具体用以下方式实现

Java八股文 ----Redis篇_第15张图片

互斥锁方案---要求强一致性的方案

Java八股文 ----Redis篇_第16张图片

共享锁(读锁):加锁以后只能共享读操作

排他锁(写锁):加锁以后阻塞其他读写操作,仅当前线程进行写操作

Java八股文 ----Redis篇_第17张图片

Redis集群

使用集群的原因

redis服务器升级至一定程度后  持久化的成本过高

当 Redis 需要持久化数据时,它需要将数据从内存中写入磁盘,这个过程会产生一定的性能开销。

Redis 的 RDB(Redis DataBase)持久化机制是通过 fork 子进程来实现的。当 Redis 需要持久化数据时,它会 fork 一个子进程,然后让子进程将数据写入一个临时文件。当持久化过程完成后,Redis 会使用这个临时文件来替换旧的 RDB 文件。

然而,如果 Redis 使用的内存过大,fork 子进程的过程可能会导致主线程阻塞时间过长。这是因为 fork 子进程需要复制父进程的内存空间,如果内存空间过大,这个过程就会变得非常耗时。因此,如果 Redis 使用的内存过大,就可能会导致主线程在 fork 子进程时阻塞过长时间,从而降低了 Redis 的性能。

Java八股文 ----Redis篇_第18张图片

集群解决方案

Redis Cluster是一个用于实现Redis集群的解决方案,它能够避免哨兵机制复杂的Master监控与选举操作,并方便地实现数据的分片处理,以提供更加高效的Redis解决方案。

Redis Cluster把所有的数据划分为16384个不同的槽位,并可以根据机器的性能把不同的槽位分配给不同的Redis实例。每个节点都与其他节点有关联,只需获得一个节点的信息,其他节点的信息也就可以获取到。

这些槽位被称作哈希槽,通过hash算法分配槽位,放入要缓存的数据

每个实例都会向其他实例/传播/自己负责的哈希槽,这样每台redis实例都记录有所有的关系信息了! 有了这样的映射关系,客户端也就知道去哪个实例上操作了

Java八股文 ----Redis篇_第19张图片

集群新增或者删除实例

当发生了删除或者新增时, 那么redis实例负责的哈希槽关系会发生变化

但是客户端是无感知的,因为客户端会发送请求到原来的redis实例

原来的实例会给出moved命令,告诉客户端重定向

客户端收到以后就会去新的实例请求, 并且更新本地缓存

总的来说就是

如果集群Redis实例存在变动,由于Redis实例之间会「通讯」

所以等到客户端请求时,Redis实例总会知道客户端所要请求的数据在哪个Redis实例上

如果已经迁移完毕了,那就返回「move」命令告诉客户端应该去找哪个Redis实例要数据,并且客户端应该更新自己的缓存(映射关系)

如果正在迁移中,那就返回「ack」命令告诉客户端应该去找哪个Redis实例要数据

为什么是16384个哈希槽?

Java八股文 ----Redis篇_第20张图片

「服务端 路由」的大致原理

服务端路由一般指的一种代理层,  专门对接客户端的请求,然后转发到Redis集群进行处理

现在比较流行的是Codis

它与Redis Cluster最大的区别是,Redis Cluster是直连Redis实例,而Codis则客户端直连Proxy,再由Proxy进行分发到不同的Redis实例进行处理

你可能感兴趣的:(面试八股文,java,redis,mybatis)