Reids面试高频总结

163 阅读9分钟

常规八股

为什么Redis快、好用呢?

Reids是用C语言开发的NOSQL数据库,将数据储存在内存中,而且提供了很多优化的数据结构,采用IO多路复用模型进行事件处理。

Redis支持哪些数据类型?

hash、set、zset、String、List,位图、地理位置、基数统计

Zset的底层数据结构,查询的时间复杂度?

底层数据结构:ziplist 和 skiplist。满足以下两个条件就用ziplist:

  • 有序集合保存的元素数量小于 128 个
  • 有序集合保存的所有元素的长度小于 64 字节

时间复杂度:O(log n)

String底层实现?

简单动态字符串(SDS)

Redis的持久化?

AOF 和 RDB

AOF是怎么做的?

开启AOF持久化后,每执行一条会更改Reids中的数据的命令,Redis就会将该命令写入AOF缓冲区中,然后再写入AOF文件中,若AOF太大,需要定期对AOF文件重写,进行压缩,最后再根据持久化方式(fsync策略)的配置来决定何时将系统内核缓冲区的数据同步到硬盘中。

RDB是怎么做的?

通过创建快照来获得存储在内存里面的数据在某个时间点上的副本

RDB的写入策略,按时间写入和每次都写入的区别,优缺点?

按时间写入: 优点:定期将数据持久化到磁盘,减少磁盘I/O操作,降低对性能的影响。 缺点:如果在两次写入操作之间发生故障,可能会导致数据丢失。

每次都写入: 优点:确保数据的实时持久化,避免数据丢失。 缺点:频繁的磁盘I/O操作可能会影响性能

我平时都怎么使用AOF和RDB的?

RDB和AOF混合持久化,当AOF重写时,直接将RDB的内容写到AOF文件的开头

Redis集群

Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。

Redis集群如何实现负载均衡?

Redis集群通过数据分片和槽位分配机制来实现负载均衡。

Redis集群的主从模型?

Redis集群的主从模型是一种重要的高可用性方案,它通过数据备份和读写分离来提高系统的性能和可靠性。

在主从模型中,包含一个主节点(Master)和一个或多个从节点(Slave)。所有的写操作都在主节点上进行,而读操作可以在主节点和从节点上进行。从节点会复制主节点的数据,实现数据的备份。具体同步步骤如下:

  1. 从服务器连接到主服务器:首先,从服务器需要连接到主服务器。这通常通过在从服务器上执行SLAVEOF命令并指定主服务器的IP地址和端口号来完成。
  2. 发送SYNC命令:从服务器连接到主服务器后,它会发送一个SYNC命令。这个命令触发主服务器开始复制过程。
  3. 主服务器开始保存数据:收到SYNC命令后,主服务器会在后台保存其数据快照,同时记录从接收到SYNC命令开始执行的所有写命令。
  4. 主服务器发送数据快照:数据快照完成后,主服务器将其发送给从服务器。从服务器接收数据快照后,会删除所有旧数据,使用新数据快照加载。
  5. 主服务器发送缓存的写命令:数据快照发送完成后,主服务器将在数据快照过程中记录的所有写命令发送给从服务器。从服务器按照接收顺序执行这些命令,确保其数据与主服务器一致。
  6. 完成主从同步:完成上述步骤后,主从服务器数据同步。之后,主服务器每执行一次写命令就会将命令发送给所有从服务器,从服务器执行该命令以确保数据一致性。

集群中如何选举主节点?

Redis 集群中,主节点的选举主要依赖于Redis Sentinel或Raft协议等机制进行管理

  • 主观下线和客观下线:每个Sentinel节点都会定期检查主节点的状态。如果一个主节点未能在规定时间内响应Sentinel的PING命令,该Sentinel节点会将其标记为主观下线。然后,Sentinel节点会询问其他Sentinel节点,如果超过半数的Sentinel节点也认为该主节点已下线(客观下线),则开始选举新主节点。
  • 选举领导者和投票:在进行选举时,每个Sentinel节点都可以发起选举请求。其他Sentinel节点如果没有已经同意过其他节点的选举请求,则会支持当前的选举请求。当一个Sentinel节点获得超过半数支持时,该节点即成为领导者,负责选举新的主节点。
  • 选择新主节点:领导者从从节点中选择一个新主节点,依据包括优先级、复制偏移量和运行ID等信息,以确保数据的同步性和一致性。

Redis的大key问题怎么解决?

  1. 拆分大key
  2. 使用hash结构
  3. 压缩数据
  4. 分片存储
  5. 定期清理
  6. 优化查询方式
  7. 监控与调优

大key问题的缺点?

  1. 阻塞请求
  2. 内存增大
  3. 阻塞网络
  4. 影响主从同步、主从切换

如果有一个接口存的是大key,QPS比较低,另外有10个接口,QPS非常高,会有什么影响?

  1. 资源竞争 :高QPS的接口可能会占用大量的CPU、内存和网络带宽资源,导致Redis实例无法充分利用其性能。在这种情况下,低QPS的大key接口可能会受到限制,响应时间可能变长。
  2. 缓存雪崩 :如果大key的数据被频繁更新或删除,可能会导致大量请求同时到达Redis,进而引发缓存雪崩现象。这种情况下,整个系统的性能都会受到影响。
  3. 数据倾斜 :由于大key的数据量较大,可能导致Redis内存使用不均衡,部分内存空间被浪费,而其他小key的空间得不到充分利用。

为什么key不是大key,但QPS非常高的接口,对性能影响没那么大?

  1. 数据量较小 :由于key不是大key,每个key对应的数据量较小,因此Redis在处理这些请求时所需的资源较少。
  2. 操作复杂度较低 :高QPS的接口可能执行的操作较为简单,如GET、SET等基本操作,这些操作通常不会占用过多的CPU和内存资源。
  3. 并发 连接数较低 :如果高QPS的接口并发连接数较低,那么Redis实例可以更好地应对这些请求,不会出现明显的性能瓶颈。
  4. 负载均衡 :如果使用了负载均衡技术,如Redis集群或分片,那么高QPS的请求会被分散到多个Redis实例上,从而减轻单个实例的压力。

本地缓存和Redis缓存的区别?

  1. 实现方式 :本地缓存通常是指将数据存储在应用程序的内存中,而Redis缓存则是一个独立的分布式缓存系统,它有自己的进程和网络通信机制。
  2. 数据持久性 :本地缓存的数据通常只存在于应用程序的运行过程中,当应用程序重启或崩溃时,缓存数据会丢失。而Redis缓存可以将数据持久化到磁盘,即使Redis服务重启,数据仍然可以恢复。
  3. 容量限制 :本地缓存的容量受限于应用程序的内存大小,如果缓存数据过多,可能会导致内存溢出。而Redis缓存可以通过配置参数来调整其最大内存限制,并支持数据的淘汰策略(如LRU、LFU等)来管理内存使用。
  4. 分布式能力 :Redis缓存支持分布式部署,可以在多台服务器上搭建集群,实现数据的高可用性和扩展性。而本地缓存通常只能在单台服务器上使用。
  5. 性能特点 :由于本地缓存直接在内存中操作,访问速度较快,但受内存大小限制;而Redis缓存虽然有一定的网络开销,但在大规模并发访问下仍能保持较高的性能。
  6. 应用场景 :本地缓存适用于对实时性要求较高、数据量较小的场景,如用户会话信息、热点数据等;而Redis缓存适用于需要高可用性、可扩展性和持久性的大规模分布式应用,如电商网站的商品信息、社交网络的用户关系等。

Redis的key过期策略?

惰性删除:只会在取key时才对数据进行过期检查。

定期删除:每隔一段时间抽取一批key执行删除过期key操作。

Reids采用:定期删除+惰性删除,并结合Redis内存淘汰机制(处理漏掉的过期key)。

Redis内存淘汰机制?

从已设置过期时间的数据集中:最近最少使用、将要过期、任意选择、最不经常使用

从所有的key中:最近最少使用、任意选择、最不经常使用