[准备面试|Redis]- 常见面试题

138 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

前言

本系列主要从基础知识,而后进阶,再逐步深入 Redis 的原理分析,以保证对 Redis 的学习深入浅出,学以致远并输出自己对 Redis 学习和了解的成果。本系列将划分四个部分:

为什么使用 Redis

  • 提高服务性能,因 redis 的操作基本都是在内存中,从 redis 中获取数据比从数据库更快
  • 并发情况下,直接操作数据库可能出现问题。将 redis 作为缓冲作用。

使用 Redis 的缺点

  • 缓存和数据库双写一致性问题
  • 缓存雪崩问题
  • 缓存击穿问题
  • 缓存的并发竞争问题

单线程的 Redis 为什么这么快

  • 操作都是在内存中
  • 拥有高效的数据结构,如哈希表,跳表
  • 单线程避免了因多线程之间竞争或切换产生性能开销,且无死锁问题
  • Redis 采用的非阻塞 I/O 多路复用机制,从而使得读写不再阻塞

单线程的处理能力应该比多线程差,但 Redis 因以上原因所以反而会更快

其实在 redis 6.0 之后增加了多线程

Redis 的数据类型,以及每个数据类型使用场景

  • 字符串类型 string,场景:常规使用,也支持一些复杂的记述功能的缓存
  • 列表类型 list,场景:简单消息队列功能, 利用 lrange 命令做基于 redis 的分页功能
  • 哈希类型 hash,场景:存储结构化对象
  • 集合类型 set ,场景:存储不重复值的集合
  • 有序集合类型 zset ,有序集合多了 score 可按 score 进行排序。 场景:排行榜,排序使用

Redis 与数据库双写一致性

数据一致性问题,若要求强一致性,则不能放在缓存内。如果没有要求强一致性场景下,采用正确的更新策略:先更新数据库,再删除缓存。

缓存穿透、缓存击穿、缓存雪崩

  • 缓存穿透

    • 查询某个 key 时不存在,缓存不命中,则需要在数据库中查询,若数据库中不存在则将无法更新缓存(某key 缓存无,数据库也没有)
    • 解决方案:预设值 null ,若为null 则无需查询数据库,避免请求访问到数据库的情况
  • 缓存击穿

    • 某热点 key 在并发且高峰期环境时,突然失效,将导致所有请求都请求到数据库,从而导致数据库压力增大
    • 解决方案:后台异步监控该热点key ,若过期了,重新设置该 key的值
  • 缓存雪崩

    • 缓存过期时间集体失效,导致大量数据无缓存,请求时直接请求到数据库
    • 解决方案:1、失效时间随机,每个缓存失效时间再加个随机值;2、设置缓存不过期

Redis 并发竞争问题

Redis 中提供事务机制,仅针对是同一服务下进行批量命令操作时使用事务机制,保证操作的原子性。在微服务环境下,若多个服务都去 set 某 key的值,事务就不合适。

所以可以使用分布式锁,服务抢到锁就进行 set 操作

Redis 过期策略以及内存淘汰机制

过期策略:Redis 采用的是定期删除+惰性删除策略

默认每 100ms 随机抽查 key 是否过期,过期就会删除。但只有定期删除无法保证所有的 key 都被删除,所以再加上惰性删除,每次你获取某个 key 的值都会检查其是否过期,如果过期了就会删除。

当然也会出现 key 定期删除没有被删除,也没有再被访问 ,这样就会一直留在内存中,就会导致内存越来越高,所以又使用内存淘汰机制

 maxmemory-policy volatile-lru

Redis 提供多种内存淘汰机制配置,不同的淘汰机制。比较推荐的是 allkeys-lru :内存不足写入新数据是,在所有 key 中,移除最近最少使用的

volatile-lru: 内存不足写入新数据时,在设置里过期时间的 key 中移除最近最少使用的。

主从复制的原理详解

  • 从库启动时会向主库发送 sync 命令
  • 主库收到命令就会执行 RDB 持久化,后续的指令缓存起来
  • 快照完后就会将快照和缓存的指令都发送给从库
  • 从库接收到指令后就会载入快照文件并执行缓里的命令
  • 之后主库接收到写命令都会同步给从库

RDB 和 AOF 持久化的原理

RDB 快照方式

  • redis 使用 fork 函数从主进程复制并创建一个子进程
  • 子进程进行持久化工作,将内容写入硬盘
  • 子进程写入所有数据后会用该临时文件替换旧的 RDB 文件

AOF 持久化,是将 redis 执行的那个命令都追加到磁盘文件中,恢复的时候只需要执行该命令文件完成持久化

Redis 哨兵机制,如何实现故障恢复自动化

哨兵的作用

  • 监控主库和从库的状态
  • 通知其他各哨兵主从库和自身的消息状态
  • 当主库出现奔溃时,就会自动实现恢复

自动化恢复故障步骤:

  • 将从库升级为主库
  • 通知客户端主库变更
  • 其他从库重新指向新的主库
  • 将之前主库变更为从库,并执行新的主库

参考资料: