[ 面试 - 干货 ]Redis基础和进阶面试

494 阅读6分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

微信公众号搜索 程序媛小庄 人生苦短 一起学Python

image.png

前情提要

小庄历经千辛万苦,终于等到下一位面试官前来,只见一个神采奕奕绝顶聪明的面试官进来,不晓得这位大佬要问些啥子问题呢?

面试开始...

面试官大佬:小伙子,上个面试官对你挺满意,那你先做个自我介绍吧~

我:(天知道我最讨厌自我介绍,继续一本正经的胡说八道)毕业于清华大学计算机专业,之前从事过xxx工作,主要使用的技术栈是xxx,由于xxx原因考虑换一份工作。

面试官大佬:嗯嗯,基本情况我已经知道了,Python这部分知识刚刚已经问的差不多了,我就简单问一下Redis相关的问题好吧。

我:好的,您问!

面试官大佬:你先说说Redis有哪些基本的数据结构。

我:Redis中有5种常用的数据结构,分别是string, list, hash, set, zsetstring数据类型可以用于常规计数,是最常用的一种数据结构;list数据类型可以作为消息队列或者进行成员关系之间的判断;hash是最接近MySQL表结构的一种数据类型可以用来做数据库缓存;set集合去重,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能;zset可以用于排行榜相关功能。

面试官大佬:嗯,基本没啥问题,那你知道为什么Redis的速度很快吗?

我:Redis是完全基于内存操作的,使用单线程模型避免了上下文的切换并且在Linux系统中redis是基于epoll模型的IO多路复用。

面试官大佬:缓存穿透 缓存击穿 缓存雪崩知道吗?

我:缓存击穿是指单个key并发访问过高,当这个key过期的时候所有的请求会打到数据库上,可能会让数据库挂掉,可以加锁更新,比如请求查询A,发现缓存中没有,对A这个key加锁,同时去数据库查询数据,写入缓存,再返回给用户,这样后面的请求就可以从缓存中拿到数据了,或者设置热点数据永不过期;
缓存雪崩是指某一时刻发生大规模的缓存失效,比如大规模的key都失效了,可能会导致数据库崩溃,可以通过针对不同的key设置不同的过期时间,避免同时过期这一方式解决问题;
缓存穿透是指访问一个不存在的key,缓存不起作用,请求会直接打到数据库,流量大的时候,数据库可能会挂掉,这种情况下可以采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤。

面试官大佬:(面露满意)嗯,可以,Redis的过期策略和内存淘汰机制晓得不?

我:redis主要有两种过期删除策略,惰性删除和定期删除。惰性删除指的是当查询key的时候才对key进行检测,如果已经达到过期时间则删除,显然惰性删除的缺点就是如果这些过期的key没有被访问,那么就一直无法被删除,而且一直占用内存。定期删除指的是redis每隔一段时间对数据库做一次检查,删除里面的过期key。由于不可能对所有key去做轮询来删除,所以redis会每次随机取一些key去做检查和删除。

假设redis每次定期随机查询key的时候没有删掉,这些key也没有做查询的话,就会导致有一些key一直保存在redis里面无法被删除,这时候就会走到redis的内存淘汰机制。在redis的配置文件中通过maxmemory-policy来配置内存淘汰机制,volatile-lru是从已设置过期时间的key中,移出最近最少使用的key进行淘汰,volatile-ttl:从已设置过期时间的key中,移出将要过期的key,volatile-random:从已设置过期时间的key中随机选择key淘汰,allkeys-lru:从key中选择最近最少使用的进行淘汰,allkeys-random:从key中随机选择key进行淘汰,noeviction:当内存达到阈值的时候,新写入操作报错

面试官大佬:(可以呀小伙子)Redis的数据持久化有了解过吗?

我:redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。redis数据持久化有两个方案,RDB和AOF。

RDB持久化是将某个时间点上的数据库状态保存到RDB文件中,RDB文件是一个压缩的二进制文件,通过它可以还原某个时刻数据库的状态。可以通过SAVE或者BGSAVE来生成RDB文件。优点是速度快,适合用于备份,缺点是可能会有数据丢失。

AOF持久化会记录服务器执行的所有写操作命令,可以通过重新执行这些命令来还原数据库。 优点可以最大程度保证数据不丢失,缺点是日志记录量比较大。

面试官大佬:嗯嗯,基本上没啥问题,稍微问一下sentinel,不知道你了解吗?

我:嗯嗯,稍微了解过一些(一定要谦逊),redis也是有主从的,但是主从缺点很明显,假设master宕机,那么就不能写入数据,那么slave也就失去了作用,整个架构就不可用了,除非你手动切换,主要原因就是因为没有自动故障转移机制。

sentinel可以同时监视多个主从服务器,并且在被监视的master下线时,自动将某个slave提升为master,然后由新的master继续接收命令。sentinel会每隔1秒向所有实例(包括主从服务器和其他sentinel)发送ping命令,并且根据回复判断是否已经下线,这种方式叫做主观下线。当判断为主观下线时,就会向其他监视的sentinel询问,如果超过半数的投票认为已经是下线状态,则会标记为客观下线状态,同时触发故障转移。

面试官大佬:(面露慈祥,哈哈)小伙子不错,我就先问到这,等等下个面试官再来考考你吧,哈哈!

我:好嘞,您慢走!