Redis 常见面试题汇总

1. 写在前面

小伙伴们有时候比较排斥这些八股,但我觉得八股就好比数学课本中的公式和课后习题,关键你要发散开,而不是搞题海战术

2. 面试题

2.1 redis变慢的原因

存储了bigkey,淘汰删除bigkey释放内存的时候会耗时比较久

redis 实例设置了内存上限maxmemory,当内存达到maxmemory,每次写入数据都会从实例剔除一部分数据,让整个实例的内存维持在maxmemory以下,然后才能把新数据写进来

开启了内存大页,当redis执行后台RDB或者AOF rewrite的时候,采用fork子进程的方式来处理,但主进程依旧可以接受处理写请求,进来的写请求采用cow写时复制的方式操作内存数据,这样的好处是父进程有任何写操作,并不会影响子进程的数据持久化,那么在此期间,客户端即便只修改10b的数据,redis在申请内存时会以2MB为单位向系统申请内存,申请内存耗时变长,进而导致每个写请求的延迟增加,影响redis性能

使用了swap, 操作系统为了缓解内存不足对应的程序影响,允许把一部分内存中的数据交换到磁盘中,已达到应用程序对内存使用的缓冲,这些内存数据被换到磁盘上的区域就是swap 当内存中的数据换到磁盘上后,redis再访问这些数据时就需要从磁盘读取,访问磁盘速度要比访问内存慢几百遍,解决方案就死增加机器的内存,让redis有足够的内存使用

网络带宽过载,服务器TCP层和网络层就会出现发送延迟,丢包等情况,redis的高性能除了操作内存就是网络IO课,如果网络IO存在瓶颈,也会影响redis的性能 解决方案:及时确认占满网络带宽的是不是属于正常的业务访问,是的话及时扩容或者迁移实例

频繁的短连接,频繁的短连接会导致redis大量时间耗在链接的建立和释放上,TCP的三次握手和四次挥手也会增加访问延迟,应该使用长连接操作redis,避免频繁的短连接

2.2 什么是redis的大key以及怎么处理

value是string,超过5MB

value 是zset、hash、list、set等集合类型的,成员数量超过1w个,也不是绝对的,根据value的成员数量和大小来确定

当value是string,可以使用序列化,压缩算法控制value的大小,但是 也会带来时间的消耗

拆分key,使用meultiget来获取

2.2 缓存击穿和穿透

击穿:大量的请求同时查询一个key的时候,这个key突然失效,导致大量的请求落到DB,击穿就是查询失效的key,穿透是查询不存在的key

如何解决击穿:

加分布式锁,并发的多个请求只有第一个请求线程拿到锁并执行数据库查询,其他线程拿不到就阻塞,第一个线程写入缓存,后续直接走缓存

热点数据不过期,设置为不过期,然后由定时任务去异步加载数据,更新缓存,要考虑业务能承受的数据不一致的时间

如何解决穿透

缓存空值,不去查数据库

采用bloom,将所有的数据hash到一个足够大的bitmap,查询不存在的数据会被bitmap拦截掉,避免DB的查询压力,可能存在,一定不存在

2.3 缓存雪崩

设置缓存的时候采用了相同的过期时间,导致缓存某一时刻同时失效,请求全部到DB,导致DB over

DB 查询加锁排队查询

设置二级缓存

2.4 sortedSet 和list的比较

相同点:有序,都可以获取某个范围的元素

不同点: 列表基于链表实现,获取两端元素快,访问中间元素速度慢,有序集合基于散列表和跳跃表,访问中间元素时间复杂度OlogN,列表不能简单的调整某个元素的位置,有序列表可以,有序集合更耗内存

2.5 redis的keys命令的问题

redis命令的执行是单线程的,keys命令会导致线程阻塞一段时间,直到执行完毕服务才能恢复

如何解决:用scan,采用渐进式遍历的方式来解决keys命令带来的阻塞问题,每次scan命令的时间复杂度是O1,但是要真正实现keys的功能,需要执行多次的scan

scan的缺点:scan的过程有crud,导致新增的key没有遍历到,遍历出现了重复的key等情况

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务