Redis面试题

  1. Redis有什么优点?
  • 1. 速度快:数据存储在内存中,类似于HashMap,操作和查找的时间复杂度都是O(1);
  • 2. 支持数据类型丰富:有字符串string,字典hash,列表list,集合set,有序集合zset
  • 3. 支持持久化

     2.Redis有什么缺点?

  • 1. 存储受内存大小限制;
  • 2. 持久化时占用cpu较大

    3.为什么redis单线程的效率这么高?

  •    1. 操作的内存,本身速度快;
  •    2. 使用单线程,避免了上下文切换。

     4.Redis有几种持久化方式?

   有全量RDB持久化和增量AOF持久化。
1. 全量RDB持久化,在指定时间,fork一个子进程,将数据写入到临时文件,完成后替换之前的文件,用二进制压缩存储。
  1.1 可以灵活设置备份频率和周期,适合冷备份,恢复快,性能最大化。
  1.2 在完成持久化之前宕机,会丢失数据;fork子进程占用资源。
2. 增量AOF持久化,将每一个非读操作,记录到文件中,使用操作恢复。
  2.1 使用追加模式,不会影响以前的数据;丢失数据量少;文件过大会重写压缩;生成的文件格式清晰,易于理解;
  2.2 生成的文件要大,恢复速度慢于RDB;运行效率低于RDB;操作回放更加脆弱。
 ———————————————— 

   5 .如何从一亿个key中找到以某个固定前缀开头的key?

  •    使用keys指令,匹配固定前缀;
  •    Redis是单线程的,keys指令会导致阻塞,是服务停顿,指令执行完毕才可以恢复。
  •    可以使用scan指令,但是可能有一定的重复,需要客户端去重,划分时间。

   6 . redis如何实现分布式锁?

  • 使用setnx来争抢锁,再用expire加一个过期时间,防止忘记释放锁;
  • 如果在执行setnx之后,expire之前发生异常,就会死锁;可以将setnx和expire合成一条指令

    7. redis如何做队列?

  •  list是双端操作的,可以使用list作为队列,一端作为生产者入队rpush,另一端作为消费者出队lpop;
  • 实现延迟队列,可以使用zortedset,使用时间作为score,zadd生产消息,zrangbyscore指定获取描述的数据。
  • 如何生产一次,消费多次? 可以使用发布订阅模式;缺点是消费者下线,消息会丢失。
     

    8 .  如果大量的key在同一时间过期,需要注意什么?

    过期时间过于集中,可能会出现短暂卡顿,可以加一个随机值,使过期时间分散一些。

    9.  什么是缓存穿透?如何解决?

  •     查询一个一定不存在的数据,缓存中不存在,则会去数据库中查询,数据库中不存在则不会写入缓存,这导致每次查询都会查询数据库,使缓存失去意义。
  • 可以使用空对象,当查询为空时,设置一个特殊的值,和真正合法数据区分开,要有一个较短的过期时间。
  • 使用过滤器,先查缓存,缓存存在key则返回;不存在则查询过滤器,过滤器存在则说明不存在值,直接返回空,否则查询数据库。

 10.  什么是缓存雪崩?如何解决?

  • 缓存无法使用导致请求全部到达数据库,导致数据库崩溃。
  • 缓存高可用,减少缓存不可用时间;数据库限流;服务降级;

  11  .什么是缓存击穿?如何解决?

  •    某个key失效时,大量的请求进入,将数据库瞬间压垮。
  •   使用锁,确保只有一个线程去查询数据库;手动过期,不设置过期时间,所有key手动过期。

  12.redis默认有多少数据库,如何指定?

  • 默认有16个数据库,下标默认从0开始。
  • 可以通过配置database选项指定。 可以通过select 下标 切换数据库。

  13.过期键删除策略?

主动删除: 1. 定时删除:创建定时器,在键过期的时候,删除键;占用cpu。

                   2. 定期删除:每隔一段时间,删除过期键。 被动删除: 惰性删除:在取出键的时候检查是否过期;有些键不被使用,永远无法删除。

  14.save和bgsave的区别?

  • save:由于redis是单线程的,save会造成阻塞,在rdb文件创建完成期间不处理任何请求。
  • bgsave:会创建子线程,完成rdb文件的创建工作,主线程正常执行。
  • 在执行bgsave期间,主线程会拒绝save和bgsave命令;bgrewriteaof命令会延迟到bgsave命令结束之后执行

15 . 旧版Redis复制过程是怎样的?

1. 同步
  1.1 从服务器向主服务器发送sync指令
  1.2 主服务器收到sync命令,执行bgsave,生成rdb文件,并使用一个缓冲区记录备份开始后     执行的所有命令。
  1.3 主服务器bgsave执行完成后,将rdb文件发送给从服务器,从服务器接受rdb文件并载入。
  1.4 主服务器将缓冲区中的所有写命令发送给从服务器,从服务器执行命令。
2. 命令传播
  2.1 主服务器会将自己的写命令同步给从服务器,从服务器执行命令。 
 

16 .  旧版同步可能的问题是什么?

  • 同步分为初次同步和断线后同步。
  • 初次同步,并没有任何问题,可以很好的完成任务。
  • 断线后同步,从服务器会再次发送sync指令,重新进行一次完整的同步。
  • 但是从服务器和主服务器之间的差异,只是断线期间的差异,进行完全同步,耗费资源。

17.memcached与redis的区别?

  •        1.存储方式不同。memcached把数据全部存在内存之中,断电之后会挂掉,而redis虽然也用到了内存,但是会有部分数据存在硬盘中,保证数据持久性。
  •   2.数据支持类型不同。memcached对数据支持比较简单,而redis支持数据类型较丰富,如string、list、set、sorted set、hash。
  •   3.底层实现不同。一般调用系统函数,会消耗比较多的时间去请求,redis自己构建了vm,速度会更快。

18.redis数据的淘汰策略?

    1.volatile-lru:从已经设置过期时间的数据集中,挑选最近最少使用的数据淘汰。

  2.volatile-ttl:从已经设置过期时间的数据集中,挑选即将要过期的数据淘汰。

  3.volatile-random:从已经设置过期时间的数据集中,随机挑选数据淘汰。

  4.allkeys-lru:从所有的数据集中,挑选最近最少使用的数据淘汰。

  5.allkeys-random:从所有的数据集中,随机挑选数据淘汰。

  6。no-enviction:禁止淘汰数据。
 ———————————————— 
19.为什么redis把所有数据都放到内存中?

  redis为了达到最快的读写速度,将数据都读到内存中,并通过异步的方式将数据写入磁盘。如果不将数据放在内存中,磁盘IO速度会严重影响redis的性能

20 . redis的并发竞争问题如何解决?

首先redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。redis本身时没有锁的概念的,redis对多个客户端连接并不存在竞争,但是在Jedis客户端对redis进行并发访问时会产生一系列问题,这些问题时由于客户端连接混乱造成的。有两种方案解决。

  1.在客户端,对连接进行池化,同时对客户端读写redis操作采用内部锁synchronized。

  2.在服务器角度,利用setnx实现锁。


21 . redis过期键的删除策略?

       1.定时删除:在设置键的过期时间的同时,创建一个timer,让定时器在键的过期时间到达时,立即执行对键的删除操作。(主动删除)对内存友好,但是对cpu时间不友好,有较多过期键的而情况下,删除过期键会占用相当一部分cpu时间。

  2.惰性删除:放任过期键不管,但是每次从键空间中获取键时,都检查取到的键是否过去,如果过期就删除,如果没过期就返回该键。(被动删除) 对cpu时间友好,程序只会在取出键的时候才会对键进行过期检查,这不会在删除其他无关过期键上花费任何cpu时间,但是如果一个键已经过期,而这个键又保留在数据库中,那么只要这个过期键不被删除,他所占用的内存就不会释放,对内存不友好。

  3.定期删除:每隔一段时间就对数据库进行一次检查,删除里面的过期键。(主动删除)

        采用对内存和cpu时间折中的方法,每个一段时间执行一次删除过期键操作,并通过限制操作执行的时长和频率来减少对cpu时间的影响。难点在于,选择一个好的策略来设置删除操作的时长和执行频率。

22 . redis与一般db的同步过程?

有两种方式。

  第一种,先去redis中判断数据是否存在,如果存在,则直接返回缓存好的数据,如果不存在,去db中读取数据,并把数据缓存一份到redis中。适用与数据里比较大,但是不经常更新的情况,如用户排行。

第二种,先去redis中判断数据是否存在,如果存在,则直接更新对应数据(这一步会记录下更新的key,并把更新后的数据返回给页面,如果不存在,先去数据库中更新内容,然后把数据保存一份到redis中。再往后,后台会进行一系列操作,把redis中更新的key读取出来,找到数据库中对应的数据,并更新数据库。这种方式是把redis当作数据库使用,适合大数据的频繁变动。但是对redis的依赖很大,要做好挂掉之后的数据备份。
 

23  .  简述redis的哨兵模式

  哨兵是对redis进行实时的监控,主要有两个功能。

  1.监测主数据库和从数据库是否正常运行。2.当主数据库出现故障的时候,可以自动将一个从数据库转换为主数据库,实现自动切换。

24 . redis的哨兵的监控机制是怎样的?

        哨兵监控也是有集群的,会有多个哨兵进行监控,当判断发生故障的哨兵达到一定数量的时候才进行修复。一个健壮的部署至少需要三个哨兵实例。

  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 的主观下线状态就会被移除
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值