Redis的面试题

1.什么是缓存穿透?怎么解决?

缓存穿透是指查询一个不存在的数值,先访问redis,redis缓存中不存在无法命中,就会访问数据库。如果高并发的访问这样的接口,会给数据库造成巨大的压力。

解决方法:在我们项目中会使用布隆过滤器来缓存穿透的问题,单缓存命中时基于布隆过滤器来判断数据是否存在,不存在就拒绝。

我们也可以使用缓存空值的方式来讲解,不过这种方案比较浪费内存。

2.能介绍一下布隆过滤器嘛?

布隆过滤器主要是用于检索一个元素是否存在一个集合中。我们当时使用的是redisson实现布隆过滤器。

他的底层主要是先初始化一个比较大的数组,里面存放的二进制的0和1。在一开始的时候都是0,当一个key来了后,经过3次的hash计算,模于数组的长度找到下标把0变成1。但是也是存在误判的概率的。

3.什么是缓存击穿?怎么解决?

缓存击穿往往是由于热点的Key引起的,当热点的key过期时,大量请求涌入同时查询,发现缓存未命中,去访问数据库,导致数据库的压力增大。

解决方法:思路:避免多线程并发去重建缓存。

(1)互斥锁。当发现缓存未命中时,需要加入互斥锁,重建缓存,缓存重建后释放锁。主要可以包中缓存在同一时间内只会有一个线程执行。 这样可能导致性能下降严重。

(2)逻辑过期,也就是不给热点Key设置过期时间,而是给数据添加一个过期时间的字段。这样热点Key就不会过期,缓存中永远有数据。

查询到数据时基于其中的过期时间判断key是否过期,如果过期开启独立新线程异步的重建缓存,而查询请求先返回旧数据即可。当然,这个过程也要加互斥锁,但由于重建缓存是异步的,而且获取锁失败也无需等待,而是返回旧数据,这样性能几乎不受影响。

需要注意的是,无论是采用哪种方式,在获取互斥锁后一定要再次判断缓存是否命中,做dubbo check. 因为当你获取锁成功时,可能是在你之前有其它线程已经重建缓存了。

  1. 什么是缓存雪崩 ? 怎么解决 ?

缓存雪崩意思是设置缓存时采用了相同的过期时间,导致缓存在某一时刻同 时失效,请求全部转发到DB,DB 瞬时压力过重雪崩。与缓存击穿的区别: 雪崩是很多key,击穿是某一个key缓存。 解决方案主要是可以将缓存失效时间分散开,比如可以在原有的失效时间基 础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重 复率就会降低,就很难引发集体失效的事件。

  1. redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

我们采用的是redisson实现的读写锁,在读的时候添加共享锁,可以保证读 读不互斥,读写互斥。当我们更新数据的时候,添加排他锁,它是读写,读 读都互斥,这样就能保证在写数据的同时是不会让其他线程读数据的,避免 了脏数据。这里面需要注意的是读方法和写方法上需要使用同一把锁才行。

面试官:那这个排他锁是如何保证读写、读读互斥的呢?

候选人:其实排他锁底层使用也是setnx,保证了同时只能有一个线程操作 锁住的方法

面试官:你听说过延时双删吗?为什么不用它呢?

候选人:延迟双删,如果是写操作,我们先把缓存中的数据删除,然后更新 数据库,最后再延时删除缓存中的数据,其中这个延时多久不太好确定,在 延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。

  1. redis做为缓存,数据的持久化是怎么做的?

1、RDB 2、AOF

7.RDB是一个快照文件,它是把redis内存存储的数据写到磁盘上,当 redis实例宕机恢复数据的时候,方便从RDB的快照文件中恢复数据。

RDB因为是二进制文件,在保存的时候体积也是比较小的,它恢复 的比较快,但是它有可能会丢数据,我们通常在项目中也会使用AOF来恢复 数据,虽然AOF恢复的速度慢一些,但是它丢数据的风险要小很多,在AOF 文件中可以设置刷盘策略,我们当时设置的就是每秒批量写入一次命令

8.这两种方式,哪种恢复的比较快呢?

RDB因为是二进制文件,在保存的时候体积也是比较小的,它恢复 的比较快,但是它有可能会丢数据,我们通常在项目中也会使用AOF来恢复 数据,虽然AOF恢复的速度慢一些,但是它丢数据的风险要小很多,在AOF 文件中可以设置刷盘策略,我们当时设置的就是每秒批量写入一次命令

8.Redis的数据过期策略有哪些 ?

第一种是惰性删除,在设置该key过期时间后,我们不去管它,当需要该key 时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。 第二种是 定期删除,就是说每隔一段时间,我们就对一些key进行检查,删 除里面过期的key 定期清理的两种模式: SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配 置文件redis.conf 的 hz 选项来调整这个次数 FAST模式执行频率不固定,每次事件循环会尝试执行,但两次间隔不低于2ms, 每次耗时不超过1ms

Redis的过期删除策略:惰性删除 + 定期删除两种策略进行配合使用。

9.Redis的数据淘汰策略有哪些 ?

这个在redis中提供了很多种,默认是noeviction,不删除任何数据,内 部不足直接报错是可以在redis的配置文件中进行设置的,里面有两个非常重要的概念,一个 是LRU,另外一个是LFU LRU的意思就是最少最近使用,用当前时间减去最后一次访问时间,这个值 越大则淘汰优先级越高。 LFU的意思是最少频率使用。会统计每个key的访问频率,值越小淘汰优先级 越高 我们在项目设置的allkeys-lru,挑选最近最少使用的数据淘汰,把一些经常 访问的key留在redis中

10.数据库有1000万数据 ,Redis只能缓存20w数据, 如何保证Redis中的 数据都是热点数据 ?

可以使用 allkeys-lru (挑选最近最少使用的数据淘汰)淘汰策略,那留下来 的都是经常访问的热点数据

11.Redis的内存用完了会发生什么?

这个要看redis的数据淘汰策略是什么,如果是默认的配置,redis内存 用完以后则直接报错。我们当时设置的 allkeys-lru 策略。把最近最常访问的 数据留在缓存中。

12.Redis分布式锁如何实现 ?

由于redis的单线程的,用了命令之后,只能有一个客户端对某一个key设置 值,在没有过期或删除key的时候是其他客户端是不能设置这个key的

13.Redis集群有哪些方案, 知道嘛 ?

候选人:嗯~~,在Redis中提供的集群方案总共有三种:主从复制、哨兵模 式、Redis分片集群

14.Redis是单线程的,但是为什么还那么快?

1、完全基于内存的,C语言编写

2、采用单线程,避免不必要的上下文切换可竞争条件

3、使用多路I/O复用模型,非阻塞IO

例如:bgsave 和 bgrewriteaof 都是在后台执行操作,不影响主线程的正常 使用,不会产生阻塞

相关推荐
best_virtuoso5 分钟前
PostgreSQL PostGIS安装与配置,现有数据库启用PostGIS扩展
数据库·postgresql
橙汁味的风5 分钟前
3关系型数据库的SQL语言
数据库·sql
学编程的董6 分钟前
07 计算字段的创建与使用 - 数据转换的艺术
数据库·oracle
程序员云帆哥22 分钟前
MySQL JDBC Driver URL参数配置规范
数据库·mysql·jdbc
TDengine (老段)40 分钟前
TDengine 数学函数 FLOOR 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
大气层煮月亮1 小时前
Oracle EBS ERP开发——报表生成Excel标准模板设计
数据库·oracle·excel
云和数据.ChenGuang1 小时前
达梦数据库的命名空间
数据库·oracle
三三木木七2 小时前
mysql拒绝连接
数据库·mysql
蹦跶的小羊羔2 小时前
sql数据库语法
数据库·sql
唐古乌梁海2 小时前
【mysql】InnoDB的聚簇索引和非聚簇索引工作原理
数据库·mysql