redis 面试题整理
前言
前天面试了一家公司,平时看一本redis书的也使用redis,对里面的东西也基本了解,结果回答的时候居然回答了只是使用了(因为认为是redis是运维的东西,做的东西多,所以忘了,好吧这是借口),因为害怕被继续问,所以说。。。。
基础的还是要快速回答出来的,前车之鉴啊。当然下面的面试题中会加入自己的一些见解。持续更新。。。。后面会加入代码全部演练一遍。
正文
redis 速度快
(一)纯内存操作
(二)单线程操作,避免了频繁的上下文切换
(三)采用了非阻塞I/O多路复用机制
二 : 这里进行一些介绍,就是说线程的切换其实是这样子的,比如说A 线程切换到B线程,那么其实是要保护好A的状态,这个状态用于后续切换到A的时候,可以进行继续操作。
三: 非阻塞 I/0多路复用机制 https://www.cnblogs.com/hello-/articles/9599380.html
redis 持久化机制
redis 是一个支持持久化的内存数据库,通过持久化吧内存的数据同步到硬盘来保证数据持久化。
当redis 重启后,通过把硬盘文件重新加载到内存中,就能达到恢复数据的目的。
实现:fork一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后子进程写入到临时文件中,持久化的过程结束,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。
RDB是redis 默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即snapshot 快照存储,对应产生的文件为 dump.rdb,通过配置文件的save 参数来定义快照的周期。
AOF:redis 会将每一个收到的写命令通过write函数追加到文件最后,类十余mysql binlog。当redis 重启会重新执行文件中保存的写命令在内存中重建整个数据库内容。
当这两种同时开启时,数据恢复redis 会优先选择AOF 恢复。
如何解决rdb中的数据丢失问题,AOF和RDB同时开启,AOF 效率低,但是只有RDB 出现问题得时候,才启动AOF。
redis 缓存雪崩
什么是缓存雪崩呢?
其实是一个很常见的一个概念,比如说数据量很大,但是设置的时间都是在同一个点,那么会产生一个问题,那就是这些数据可能在同一个时间过期,那么这个时候所有的查询都去查询数据库了。
那么这个时候最好是时间错开从而达到目的。
1.给缓存的失效时间,加上一个随机值,避免集体失效。
2.使用互斥锁,吞吐量明显下降。
3.使用双缓存,比如说缓存A、B。缓存A的失效时间为5分钟,缓存B不设置失效时间。
步骤如下:
1.A 有数据就从A 中读取。
2.A没有数据,直接从B读取数据,直接返回,并且开启一个异步线程,去更新A中的数据。
3.更新线程中同时去更新A和缓存B。
redis 缓存穿透
缓存穿透是指用户查询的数据,数据库中不存在,那么缓存中也没有,那么这个时候会一直查询数据库,所以叫做穿透。
解决方法:
1.布隆过滤器
将所有可能存在的数据哈希到一个足够大的bitmap中,一个不存在的数据会被bitmap拦截,从而避免了对底层存储系统的查询压力。
2.如果查询到的数据为空,依然对这个结果进行缓存,但是他的过期时间小,这样就不会出现缓存击穿的情况。
了解布隆过滤器。
个人见解:这其实有一种很老套的攻击手法,以前的时候很多人就通过每次查询的是一些数据库里面不存在的信息,那么每次都会去查询数据库。
缓存预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样可以避免用户在请求的时候先查询数据库。
解决思路:
1、直接写个缓存刷新页面,上线时手工操作下;
2、数据量不大,可以在项目启动的时候自动进行加载;
3、定时刷新缓存;
缓存降级
缓存降级是指当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
redis 缓存失效策略
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡。
redis 线程模型
文件事件处理器分别包括套接字、IO多路复用程序、文件事件分派器、一级事件处理器。
使用多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的时间处理器。
当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。
I/O 多路复用程序负责监听多个套接字, 并向文件事件分派器传送那些产生了事件的套接字。
redis 五种模型
相对用户而已:
1.string
value 可以是string 也可以是数字,一般做一些复杂的计算功能的缓存。
2.hash
value 存放的是结构化的对象,比较方便的就是操作其中的某个字段。
比如说单点登录的时候,这种数据结构存储用户信息,cookieId 作为key,设置30分钟缓存来作为过期时间。
3.list
可以作为简单的消息队列功能,先进先出原则很好作为队列。还可以通过lrang,做基于redis的分页功能,性能极佳,用户体验好。
4.set
set 可以作为一个去重的集合。
同时,可以进行交集、并集、补集等操作,比如说计算共同爱好。
5.sorted set
sorted set 比set 多了一个score,可以按照score进行排序,排行榜等。