Redis面试题总结

以下为个人总结的Reids面试题目,后续还会继续补充,题目排名不分先后,想到哪写到哪吧

1、Redis 常用数据结构

数据类型使用场景
StringK-V类型,常规计数,粉丝数
HashK-V映射表 ,适合用来储存对象
Set去重集合,共同好友,共同喜好,集合求交求异
List双端队列,关注列表,粉丝列表
Sorted set有权重的集合,可排序,底层为跳表,礼物排行,在线用户列表

跳表、红黑树、AVL时间复杂度都是log(n),为何用跳表?
reason1:跳表实现相对简单
reason2:红黑树等在维护顺序时会进行rebalance,可能涉及树的大部分,而跳表的修改则更加局部化一些

2、Redis和Memcached的区别

(1)Redis支持丰富的数据类型,Memcached只支持String
(2)Redis支持持久化,可以将内存中的数据保持在磁盘中 ,Memcached只能放在内存
(3)Redis原生支持集群模式,Memcached需要依靠客户端实现往集群中分片写入数据
(4)Redis为单线程,I/O多路复用;Memcached为多线程,NIO

3、Redis为什么快

1、基于内存
2、单线程I/O复用

4、Redis设置过期时间以及内存淘汰机制

Redis可以给数据库中的值设置expire time ,可以指定key的存活时间,常用于token或带过期时间的验证码

内存淘汰机制

定期删除+惰性删除
定期删除 :Redis默认每隔100ms 随即抽取带过期时间的Key,检查是否过期,如果不随机几十万的Key会使CPU负载过大
惰性删除:定期删除具有随机性,系统调用key时检查是否过期

以上两种方式还是会造成大量过期的key堆积在内存导致内存耗尽故还需要内存淘汰机制
Redis提供6中内存淘汰机制:
(1)volatile-lru ,从设置了过期时间的key集中删除最近最久未使用的数据淘汰
(2)内存不足容纳新的数据时,在所有键空间中移除最近最少使用的key(默认)
其他不赘述

5、Reids持久化

AOF(append-on-file)

记录每条会更改Reids数据的命令,实时性好,主流的持久化方案,默认情况下关闭,有以下三中方式

appendfsync always # 每次有数据更新都会写入AOF文件,会降低Redis的速度

appendfsync always #每秒更新一次AOF文件

appendfsync always #让操作系统决定何时进行同步

RDB(数据快照)

记录数据在某一时刻数据状态(Redis默认持久化方式)
三种方式
SAVE 900 1 #900s之后,至少有1个key变化,则创建快照
SAVE 300 10 #900s之后,至少有1个key变化,则创建快照
SAVE 60 10000 #900s之后,至少有1个key变化,则创建快照

6、缓存雪崩 &缓存穿透

缓存雪崩:缓存同一时间大面积失效
解决方法:
(一)缓存失效时间加一个随机值,避免集体失效
(二)使用互斥锁
(三)双缓存 一个缓存失效时间为短期 一个为长期
缓存击穿:故意请求缓存中不存在的数据,导致所有请求直接怼在数据库上
解决方法:
(一)使用互斥锁
(二)缓存空对象 缓存层不命中后,仍然将空对象保留到缓存层中,之后再访问这个数据将会从缓存中获取,保护了后端数据源( 空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。
(三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回

7、缓存数据库一致性

不整那么复杂了,说个最经典的缓存+数据库读写:

  • 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
  • 更新的时候,先更新数据库,然后再删除缓存。
    为什么是删除不是更新?
    在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值,有可能涉及到数据库的多次查询计算,但并不是每次修改数据库都需要更新缓存,举个栗子,一个缓存涉及的表的字段,在 1 分钟内就修改了 20 次,或者是 100 次,那么缓存更新 20 次、100 次;但是这个缓存在 1 分钟内只被读取了 1 次,有大量的冷数据。实际上,如果你只是删除缓存的话,那么在 1 分钟内,这个缓存不过就重新计算一次而已,开销大幅度降低。用到缓存才去算缓存。
    其实删除缓存,而不是更新缓存,就是一个 lazy 计算的思想,不要每次都重新做复杂的计算,不管它会不会用到,而是让它到需要被使用的时候再重新计算。
    为什么不用先删除缓存,然后再更新数据库?
    该方案会导致不一致的原因是。同时有一个请求A进行更新操作,另一个请求B进行查询操作。那么会出现如下情形:
    (1)请求A进行写操作,删除缓存
    (2)请求B查询发现缓存不存在
    (3)请求B去数据库查询得到旧值
    (4)请求B将旧值写入缓存
    (5)请求A将新值写入数据库
    上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。

8、哨兵机制

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

Sentinel的工作方式:
1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值