熟悉这几道 Redis 高频面试题,面试不用愁

一、说说 Redis 都有哪些应用场景?

  • 缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不只能够加 快数据的访问速度,并且可以有效地下降后端数据源的压力。
  • 共享Session:对于一些依赖 session 功能的服务来讲,若是须要从单机变成集群的话,能够选择 redis 来统一管理 session。
  • 消息队列系统:消息队列系统能够说是一个大型网站的必备基础组件,由于其具备业务 解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功 能,虽然和专业的消息队列比还不够足够强大,可是对于通常的消息队列功 能基本能够知足。好比在分布式爬虫系统中,使用 redis 来统一管理 url队列。
  • 分布式锁:在分布式服务中。能够利用Redis的setnx功能来编写分布式的锁,虽然这个可能不是太经常使用。

固然还有诸如排行榜、点赞功能均可以使用 Redis 来实现,可是 Redis 也不是什么均可以作,好比数据量特别大时,不适合 Redis,咱们知道 Redis 是基于内存的,虽然内存很便宜,可是若是你天天的数据量特别大,好比几亿条的用户行为日志数据,用 Redis 来存储的话,成本至关的高。面试

二、单线程的 Redis 为何这么快?

Redis 有多快?官方给出的答案是读写速度 10万/秒,这个数字不让人意外,可是 Redis 是单线程的。为何单线程的 Redis 速度这么快?缘由有如下三点:redis

  • 纯内存操做:Redis 是彻底基于内存的,因此读写效率很是的高,固然 Redis 存在持久化操做,在持久化操做是都是 fork 子进程和利用 Linux 系统的页缓存技术来完成,并不会影响 Redis 的性能。
  • 单线程操做:单线程并非坏事,单线程能够避免了频繁的上下文切换,频繁的上下文切换也会影响性能的。
  • 合理高效的数据结构
  • 采用了非阻塞 I/O 多路复用机制:多路I/O复用模型是利用 select、poll、epoll 能够同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,因而程序就会轮询一遍全部的流(epoll 是只轮询那些真正发出了事件的流),而且只依次顺序的处理就绪的流,这种作法就避免了大量的无用操做。

三、说说 Redis 的数据结构及使用场景

Redis 提供了 5种数据结构,每一种数据结构有各类的使用场景。数据库

一、String 字符串后端

字符串类型是 Redis 最基础的数据结构,首先键都是字符串类型,并且 其余几种数据结构都是在字符串类型基础上构建的,咱们常使用的 set key value 命令就是字符串。经常使用在缓存、计数、共享Session、限速等。缓存

二、Hash 哈希微信

在Redis中,哈希类型是指键值自己又是一个键值对 结构,形如value={{field1,value1},...{fieldN,valueN}},添加命令:hset key field value。哈希能够用来存放用户信息,好比实现购物车session

三、List 列表数据结构

列表(list)类型是用来存储多个有序的字符串。能够作简单的消息队列的功能。另外,能够利用 lrange 命令,作基于 Redis的分页功能,性能极佳,用户体验好。架构

四、Set 集合dom

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不容许有重复元素,而且集合中的元素是无序的,不能经过 索引下标获取元素。利用 Set 的交集、并集、差集等操做,能够计算共同喜爱,所有的喜爱,本身独有的喜爱等功能。

五、Sorted Set 有序集合

Sorted Set 多了一个权重参数 Score,集合中的元素可以按 Score 进行排列。能够作排行榜应用,取 TOP N 操做

四、说一说 Redis 的数据过时策略

先给你们一个结论,Redis 中数据过时策略采用按期删除+惰性删除策略

一、按期删除、惰性删除策略是什么?

  • 按期删除策略:Redis 启用一个定时器定时监视全部的 key,判断key是否过时,过时的话就删除。这种策略能够保证过时的 key 最终都会被删除,可是也存在严重的缺点:每次都遍历内存中全部的数据,很是消耗 CPU 资源,而且当 key 已过时,可是定时器还处于未唤起状态,这段时间内 key 仍然能够用。
  • 惰性删除策略:在获取 key 时,先判断 key 是否过时,若是过时则删除。这种方式存在一个缺点:若是这个 key 一直未被使用,那么它一直在内存中,其实它已通过期了,会浪费大量的空间。

二、按期删除+惰性删除策略是如何工做的?

这两种策略自然的互补,结合起来以后,定时删除策略就发生了一些改变,不在是每次扫描所有的 key 了,而是随机抽取一部分 key 进行检查,这样就下降了对 CPU 资源的损耗,惰性删除策略互补了为检查到的key,基本上知足了全部要求。可是有时候就是那么的巧,既没有被定时器抽取到,又没有被使用,这些数据又如何从内存中消失?不要紧,还有内存淘汰机制,当内存不够用时,内存淘汰机制就会上场。Redis 内存淘汰机制有如下几种策略:

  • noeviction:当内存不足以容纳新写入数据时,新写入操做会报错。(Redis 默认策略)
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(推荐使用)
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,移除最近最少使用的 Key。这种状况通常是把 Redis 既当缓存,又作持久化存储的时候才用。
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,随机移除某个 Key。
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,有更早过时时间的 Key 优先移除。

配置内存淘汰机制只须要在 redis.conf 配置文件中配置 maxmemory-policy 参数便可。

五、如何解决 Redis 缓存穿透和缓存雪崩问题

缓存雪崩: 因为缓存层承载着大量请求,有效地 保护了存储层,可是若是缓存层因为某些缘由不能提供服务,好比 Redis 节点挂掉了,热点 key 所有失效了,在这些状况下,全部的请求都会直接请求到数据库,可能会形成数据库宕机的状况。

预防和解决缓存雪崩问题,能够从如下三个方面进行着手:

  • 一、使用 Redis 高可用架构:使用 Redis 集群来保证 Redis 服务不会挂掉
  • 二、缓存时间不一致: 给缓存的失效时间,加上一个随机值,避免集体失效
  • 三、限流降级策略:有必定的备案,好比个性推荐服务不可用了,换成热点数据推荐服务

缓存穿透: 缓存穿透是指查询一个根本不存在的数据,这样的数据确定不在缓存中,这会致使请求所有落到数据库上,有可能出现数据库宕机的状况。

预防和解决缓存穿透问题,能够考虑如下两种方法:

  • 一、缓存空对象: 将空值缓存起来,可是这样就有一个问题,大量无效的空值将占用空间,很是浪费。
  • 二、布隆过滤器拦截: 将全部可能的查询key 先映射到布隆过滤器中,查询时先判断key是否存在布隆过滤器中,存在才继续向下执行,若是不存在,则直接返回。布隆过滤器有必定的误判,因此须要你的业务容许必定的容错性。

最后

目前互联网上不少大佬都有 Redis 高频面试题相关文章,若有雷同,请多多包涵了。原创不易,码字不易,还但愿你们多多支持。若文中有所错误之处,还望提出,谢谢。

欢迎扫码关注微信公众号:「平头哥的技术博文」,和平头哥一块儿学习,一块儿进步。

平头哥的技术博文