天下无难试之Redis面试刁难大全
1、Redis有哪些数据结构?
-
字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。
-
如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。
-
如果你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
-
使用过Redis分布式锁么,它是什么回事?
- 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
-
这时候对方会告诉你说你回答得不错,然后接着问如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
- 这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!对方这时会显露笑容,心里开始默念:摁,这小子还不错。
-
假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?
- 使用keys指令可以扫出指定模式的key列表。
-
对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
- 这个时候你要回答redis关键的一个特性:redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
-
使用过Redis做异步队列么,你是怎么用的?
- 一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
-
如果对方追问可不可以不用sleep呢?
- list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
-
如果对方追问能不能生产一次消费多次呢?
- 使用pub/sub主题订阅者模式,可以实现1:N的消息队列。
-
如果对方追问pub/sub有什么缺点?在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
-
如果对方追问redis如何实现延时队列?
- 我估计现在你很想把面试官一棒打死如果你手上有一根棒球棍的话,怎么问的这么详细。但是你很克制,然后神态自若的回答道:使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。
-
如果有大量的key需要设置同一时间过期,一般需要注意什么?
- 如果大量的key过期时间设置的过于集中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。
-
Redis如何做持久化的?
- bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件重新构建内存,再使用aof重放近期的操作指令来实现完整恢复重启之前的状态。
-
对方追问那如果突然机器掉电会怎样?
- 取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
-
对方追问bgsave的原理是什么?
- 你给出两个词汇就可以了,fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
-
Pipeline有什么好处,为什么要用pipeline?
- 可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。
-
Redis的同步机制了解么?
- Redis可以使用主从同步,从从同步。
第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
- Redis可以使用主从同步,从从同步。
-
是否使用过Redis集群,集群的原理是什么?
- Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
- Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
原文链接地址 : 天下无难试之Redis面试刁难大全
新增问题
-
问题:如果一个键过期了,那么它什么时候会被删除呢?有三个答案
定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在过期时间来临时,立即执行对键的删除操作 .。
这种过期策略对内存友好,但对CPU是非常不友好的。因为还要主动设定定时器并主动删除,即通过CPU换内存(CPU主动删除了内存中的数据嘛,CPU忙,内存空闲)。可以想象一下在大数据大并发的时候,这种机制是多么灾难惰性删除(Lazy Expiration):redis内部不会监视记录是否过期,但是每次从键空间获取键时,检查记录是否过期。这种技术被称为lazy(惰性)expiration。
与定时删除相反,此删除机制对内存是不友好的对CPU是友好的,惰性删除不会主动去删除已到期(expire)的键,而是等有需要调用的时候再判断,即内存换CPU(内存中有大量残留数据)定期删除:每隔一段时间,对redis数据库进行一次检查,删除里面的过期键
属于前两种方法的折中.但要注意操作检查执行的时间和频率,如果删除操作做的太频繁,或者检查执行的时间太长,定期策略就会退化成定时策略。如果检查执行的频率太少或者检查执行的时间太少,就会变成和惰性策略一样。
Redis服务器实际使用的是惰性删除和定期删除策略两种策略,配合使用两种策略和在使用CPU和内存找到平衡点。
惰性删除为redis服务器内置策略,定期删除在redis.conf 的hz选项,默认为10 (即1秒执行10次,100ms一次)
微信扫码关注java技术栈,每日更新面试题目和答案,并获取Java面试题和架构师相关题目和视频。