目录
[1.1、介绍一下什么是 Redis,有什么特点](#1.1、介绍一下什么是 Redis,有什么特点)
[1.2、Redis 为什么是单线程模型](#1.2、Redis 为什么是单线程模型)
[2.2、ZSet 为什么使用跳表,而不是红黑树](#2.2、ZSet 为什么使用跳表,而不是红黑树)
[4、AOF 的重写机制是怎样的](#4、AOF 的重写机制是怎样的)
[1、Redis 的主从同步 / 主从复制是怎么回事](#1、Redis 的主从同步 / 主从复制是怎么回事)
[1、介绍下 Redis 哨兵](#1、介绍下 Redis 哨兵)
[1、Redis 的集群是干什么的](#1、Redis 的集群是干什么的)
[2、Redis 的哈希槽是怎么回事](#2、Redis 的哈希槽是怎么回事)
[3、Redis 集群的最大节点个数是多少](#3、Redis 集群的最大节点个数是多少)
[4、Redis 集群会有些操作丢失吗](#4、Redis 集群会有些操作丢失吗)
[5、Redis 集群如何选择数据库](#5、Redis 集群如何选择数据库)
[4.1、Redis 的常见应用场景有哪些](#4.1、Redis 的常见应用场景有哪些)
[4.2、如何使用 Redis 作为消息队列](#4.2、如何使用 Redis 作为消息队列)
[4.3、如何使用 Redis 实现分布式锁](#4.3、如何使用 Redis 实现分布式锁)
[6.1、怎样测试 Redis 服务器的连通性](#6.1、怎样测试 Redis 服务器的连通性)
[6.2、如何设置 key 的过期时间](#6.2、如何设置 key 的过期时间)
[6.3、为什么在生产环境上不应该使用 keys * 命令](#6.3、为什么在生产环境上不应该使用 keys * 命令)
[6.4、Redis 的常用管理命令有哪些](#6.4、Redis 的常用管理命令有哪些)
[6.5、Redis 的 pipeline(流水线)是什么](#6.5、Redis 的 pipeline(流水线)是什么)
[6.6、Redis 如何遍历 key](#6.6、Redis 如何遍历 key)
[7.1、Redis 和 MySQL 如何保证双写一致性](#7.1、Redis 和 MySQL 如何保证双写一致性)
[7.2、什么是 Redis 的 "bigkey" 问题?如何解决](#7.2、什么是 Redis 的 “bigkey” 问题?如何解决)
[7.3、如何实现 Redis 高可用](#7.3、如何实现 Redis 高可用)
[7.4、什么是热 key 问题?如何解决](#7.4、什么是热 key 问题?如何解决)
[7.5、如何理解 Redis 的事务?和 MySQL 的事务有啥区别](#7.5、如何理解 Redis 的事务?和 MySQL 的事务有啥区别)
[1、Redis 事务本质:](#1、Redis 事务本质:)
[2、与MySQL 事务的区别](#2、与MySQL 事务的区别)
[7.6、Redis 用到的网络通讯协议是怎样的](#7.6、Redis 用到的网络通讯协议是怎样的)
[7.7、Redis 如何实现 "查找附近的人"?](#7.7、Redis 如何实现 “查找附近的人”?)
一、基础概念类
1.1、介绍一下什么是 Redis,有什么特点
1、定义:
高性能的 key-value 内存数据库,以键值对形式存储数据,支持持久化到硬盘,不依赖 "表" 结构,核心优势是简单易用和高性能。
2、核心特点:
- 纯内存存储,读写速度极快;
- 支持字符串、哈希、列表等多种数据结构;
- 支持 RDB 和 AOF 两种持久化方式;
- 单线程处理命令(6.0 后多线程处理网络 / IO,命令执行仍单线程);
- 支持主从复制、哨兵模式、集群部署;
- 支持事务、Lua 脚本、多语言客户端;
- 提供键过期、发布订阅、流水线等附加功能。
1.2、Redis 为什么是单线程模型
核心逻辑简单,性能瓶颈多在内存或 IO,而非 CPU,多线程无明显收益;
避免多线程带来的线程安全问题和线程切换开销;
6.0 后引入多线程优化:仅用于处理网络请求和协议解析,命令执行仍保持单线程,提升 IO 处理效率。
1.3、Redis为什么把数据放到内存中
**核心原因:**内存访问速度远超硬盘(内存随机访问约 100ns,硬盘随机访问约 10ms),直接奠定高性能基础;
**补充:**内存数据易丢失,因此通过 RDB/AOF 持久化机制备份到硬盘,兼顾性能和数据安全性。
二、数据类型与底层实现类
2.1、Redis支持的数据类型和内部编码
1、数据类型
核心 5 种: 字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)
扩展类型:Bitmap(位图)、HyperLogLog(基数统计)、GEO(地理信息)、Stream(消息队列)
2、内部编码(由Redis自动切换)

2.2、ZSet 为什么使用跳表,而不是红黑树
两者时间复杂度一致(插入 / 查询 / 删除均为 O (logN));
跳表实现更简单,无需红黑树的平衡调整操作,更适合 Redis 的设计理念。
三、核心功能类
3.1、持久化机制
1、Redis持久化机制
两种方式:RDB(快照持久化)和 AOF(日志持久化)
2、RDB持久化触发条件
手动触发:执行 save(阻塞主进程)或 bgsave(创建子进程,非阻塞)命令
自动触发:配置文件;主从复制;关闭Redis
生成 RDB 期间,Redis 是否可以处理写请求
- save命令:阻塞主进程,无法处理写请求;
- bgsave 命令:创建子进程生成 RDB,主进程正常处理写请求,新写入数据不会同步到本次 RDB,需下次触发 RDB 时持久化。
3、AOF文件同步策略

4、AOF 的重写机制是怎样的
- 目的:压缩 AOF 文件体积,去除无效命令、合并重复命令;
- 触发方式:手动执行
bgrewriteaof命令,或通过auto-aof-rewrite-min-size(默认 64MB)和auto-aof-rewrite-percentage自动触发; - 核心逻辑:子进程基于当前内存数据生成新 AOF 文件,主进程将重写期间的修改写入缓冲区,重写完成后合并缓冲区数据到新文件,替换旧文件。
3.2、主从复制
1、Redis 的主从同步 / 主从复制是怎么回事
核心作用: 提高可用性(主节点故障时从节点兜底)、分担读压力(主写从读);
实现方式 :从节点启动时通过
slaveof命令指定主节点,自动清空自身数据并全量复制主节点数据,后续主节点数据修改会实时同步到从节点;**特点:**主节点支持读写,从节点默认只读(slave-read-only=yes)。
2、主从复制的核心流程
- 从节点保存主节点地址信息;
- 建立 TCP 连接,发送 ping 命令验证主节点可用性;
- 权限验证(主节点设密码时,从节点需配置 masterauth);
- 数据同步(首次全量复制,后续部分复制);
- 命令持续同步(主节点实时将修改命令发送给从节点)。
3.3、哨兵模式
1、介绍下 Redis 哨兵
定义: Redis 高可用解决方案,由多个哨兵节点组成,监控主从节点状态,自动完成故障发现和故障转移;
核心功能:
- 监控:定期检测数据节点和其他哨兵节点是否可达;
- 故障转移:主节点故障时,选举新主节点并维护主从关系;
- 通知:将故障转移结果告知应用方。
2、哨兵发现主节点宕机后,会做哪些事情
**主观下线(SDOWN):**单个哨兵节点检测到主节点无心跳,标记为主观下线;
客观下线(ODOWN): 多个哨兵节点协商,达成法定票数(超过半数)后,标记主节点客观下线;
选举 leader 哨兵: 通过 Raft 算法选举一个哨兵节点作为 leader,负责后续故障转移;
故障转移执行:
- 从所有从节点中筛选新主节点(优先级 ;复制偏移量 ;run id);
- 让新主节点执行
slaveof no one,晋升为主节点;- 让其他从节点同步新主节点数据;
- 原主节点恢复后,将其设为新主节点的从节点。
3.4、集群模式
1、Redis 的集群是干什么的
核心目的: 解决单节点存储容量限制,实现数据分布式存储,同时保证高可用和扩展性;
**原理:**将数据分片存储在多个主节点上,每个主节点搭配从节点,主节点故障时从节点自动补位
2、Redis 的哈希槽是怎么回事
核心机制: Redis 集群将 16384 个哈希槽(0-16383)分配给各个主节点,每个主节点负责部分槽位;
分片规则: hash_slot = crc16(key) % 16384,根据键的哈希槽值确定存储的主节点;
**优势:**扩容 / 缩容时仅需迁移部分槽位数据,无需全量迁移,效率更高
3、Redis 集群的最大节点个数是多少
作者建议:不超过 1000 个主节点(基于哈希槽分配和集群稳定性考虑)
4、Redis 集群会有些操作丢失吗
Redis并不能保证数据的强一致性,在极端情况下可能会丢失写操作
比如:在写成功一个key之后,正好主节点宕机,此时由于这个数据还没有来得及同步到从节点上,也没来得及AOF写入日志,就丢失了 。
5、Redis 集群如何选择数据库
集群模式不支持选择数据库,仅能使用默认的数据库 0
四、应用场景类
4.1、Redis 的常见应用场景有哪些
- 缓存:存储热点数据,降低数据库访问压力,加速读写;
- 计数器:统计视频播放量、商品浏览数等,支持原子增减操作;
- 排行榜:基于 zset 实现按热度、时间等维度的排行榜;
- 分布式会话:集中存储用户登录信息,解决分布式系统会话共享问题;
- 分布式锁:基于
setnx+ 过期时间 + Lua 脚本实现,控制分布式系统并发访问;- 消息队列:通过 List(阻塞队列)、Pub/Sub 或 Stream 实现简单消息队列;
- 社交功能:实现点赞、粉丝、共同好友等功能(基于集合交集 / 并集操作);
- 地理信息:基于 GEO 类型实现 "附近的人" 等 LBS 功能。
4.2、如何使用 Redis 作为消息队列
-
List 实现:生产者用
lpush/rpush写入,消费者用**blpop/brpop**阻塞读取,适合简单队列场景; -
Pub/Sub 实现:基于发布订阅模式,支持多消费者订阅,无消息持久化;
-
Stream 实现:Redis 5.0 新增,支持消息持久化、分组消费、ACK 机制,功能最完善。
4.3、如何使用 Redis 实现分布式锁
- 加锁:
set key 服务器ID NX EX 10s(key 为锁标识,NX 保证仅不存在时设置,EX 设过期时间防死锁)- 解锁:通过 Lua 脚本原子执行 "判断服务器 ID 一致→删除 key",避免误删其他节点的锁
- 优化:
- 看门狗(watch dog):加锁节点启动独立线程,定期为未完成的任务续期过期时间
- Redlock 算法:向多个 Redis 节点加锁,超过半数节点加锁成功则视为锁生效,提升分布式场景下的可靠性
五、缓存相关问题类
5.1、什么是缓存穿透、缓存雪崩、缓存击穿
缓存穿透: 访问的 key 在 Redis 和数据库中均不存在,导致请求直接穿透到数据库,持续占用数据库资源;
缓存雪崩: 短时间内大量 key 过期(或 Redis 宕机),缓存失效,大量请求直接冲击数据库;
缓存击穿: 热点 key 突然过期,大量并发请求直接访问数据库,导致数据库压力骤增。
5.2、缓存穿透、雪崩、击穿的解决方案
1、缓存穿透
严格校验请求参数(如手机号、ID 格式校验);
数据库不存在的 key 也存入 Redis(值设为空字符串),设置短期过期时间;
使用布隆过滤器预判 key 是否存在,不存在则直接返回。
2、缓存雪崩
部署高可用 Redis 集群(主从 + 哨兵),避免单点宕机;
key 过期时间添加随机因子(如原 1 小时过期,改为 50-70 分钟随机),分散过期时间;
核心业务 key 不设置过期时间。
3、缓存击穿
热点 key 设为永不过期;
访问数据库时加分布式锁,限制并发请求数;
服务降级:热点 key 过期时,返回默认数据或提示 "服务繁忙"。
5.3、缓存更新策略
**定期生成:**统计周期内热点数据,批量写入缓存(实时性低)
实时生成:
缓存未满:查询未命中时,从数据库加载数据并写入缓存;
缓存满时:触发淘汰策略删除旧数据,支持的策略包括 LRU(最近最少使用)、LFU(最近 最不常使用)、FIFO(先进先出)等。
5.4、Redis淘汰策略
**触发条件:**内存不足时,新增 key 会触发淘汰
核心策略:
- 范围划分:
volatile-*(仅淘汰带过期时间的 key)、allkeys-*(淘汰所有 key);- 按算法划分:
lru(上次访问时间最老的)、lfu(最近访问次数最少得)、random(随机)、ttl(淘汰剩余过期时间最短的);- 特殊策略:
noeviction(默认),内存不足时新增操作报错。
六、命令与操作类
6.1、怎样测试 Redis 服务器的连通性
执行
ping命令,服务器返回PONG表示连通正常。
6.2、如何设置 key 的过期时间
方式 1:
set key value EX seconds(设置值时直接指定秒级过期);方式 2:
expire key seconds(单独为已存在的 key 设置秒级过期);毫秒级:
PX milliseconds(set 选项)或pexpire key milliseconds
6.3、为什么在生产环境上不应该使用**keys ***命令
时间复杂度 O (N),数据量较大时会阻塞 Redis 主进程,导致其他请求无法响应,引发生产故障
替代方案:使用
scan命令渐进式遍历(每次 O (1),多次执行完成遍历)
6.4、Redis 的常用管理命令有哪些
dbsize:返回当前数据库 key 数量;info:查看 Redis 服务器状态和统计信息;monitor:实时监听所有请求;shutdown:同步数据到磁盘并关闭服务;config get/set parameter:获取 / 设置配置参数;flushdb:删除当前数据库所有 key(慎用);flushall:删除所有数据库的 key(慎用);unlink key:异步删除 key(适合 bigkey,避免阻塞)
6.5、Redis 的 pipeline(流水线)是什么
**定义:**将多个 Redis 命令合并为一个请求发送,减少网络往返次数(RTT);
特点: 命令执行非原子性,仅批量传输,节省网络开销;
**用法:**通过客户端工具(如 redis-cli --pipe)或代码客户端批量提交命令
6.6、Redis 如何遍历 key
推荐使用
scan命令:SCAN cursor [MATCH pattern] [COUNT count]特点:
- 游标从 0 开始,返回结果包含 "下次游标",游标为 0 时遍历结束;
- 支持模糊匹配(MATCH)和指定每次返回数量(COUNT);
- 对应结构专属命令:
hscan(哈希)、sscan(集合)、zscan(有序集合)
七、其他问题
7.1、Redis 和 MySQL 如何保证双写一致性
**核心原则:**避免 "修改数据库后缓存未更新" 或 "缓存更新后数据库未修改"
解决方案:
方案 1:延时双删
删除缓存 → 更新数据库 → 延迟一段时间再次删除缓存;

方案 2:删除缓存重试
更新数据库 → 尝试删除缓存,失败则存入 MQ 重试,确保缓存删除成功

7.2、什么是 Redis 的 "bigkey" 问题?如何解决
**定义:**key 对应的 value 占用大量存储空间(如长字符串、包含大量元素的 hash/set)
**危害:**读写性能下降、集群分片数据倾斜、删除时阻塞 Redis
解决方案:
拆分 bigkey:将一个大 key 拆分为多个小 key 存储;
查找 bigkey:使用
redis-cli --bigkey命令;安全删除:用
unlink命令异步删除,避免阻塞
7.3、如何实现 Redis 高可用
核心架构:主从复制 + 哨兵 + 集群
- 主从复制:实现数据备份和读写分离;
- 哨兵:自动完成主节点故障转移;
- 集群:解决单节点存储容量限制,实现负载均衡和扩展性
7.4、什么是热 key 问题?如何解决
**定义:**某个 key 访问频率极高,集中冲击同一集群分片,导致该分片压力过大
解决方案:
热 key 所在分片增加从节点,分担读压力;
应用层对热 key 二次哈希,分散到多个分片存储;
单独为热 key 部署专属 Redis 集群;
应用层本地缓存热 key,减少 Redis 访问次数
7.5、如何理解 Redis 的事务?和 MySQL 的事务有啥区别
1、Redis 事务本质:
将多个命令放入 "事务队列",执行 EXEC 后批量执行,核心保证 "连续执行,不被其他命令插队";
2、与MySQL 事务的区别
- 原子性:Redis 无回滚机制,单个命令失败不影响其他命令执行;
- 一致性:不涉及约束校验,无中间非法状态保障;
- 隔离性:单线程执行,无需隔离级别;
- 持久性:依赖 Redis 持久化配置,与事务本身无关
3、相关命令:
MULTI(开启事务)
EXEC(执行事务)
DISCARD(放弃事务)
WATCH(监控 key,值变更则事务失效)
7.6、Redis 用到的网络通讯协议是怎样的
- 协议名称:Redis Serialization Protocol(RESP),专为 Redis 设计的应用层协议;
- 特点:纯文本协议,兼容性好、实现简单、可读性强。
7.7、Redis 如何实现 "查找附近的人"?
使用 GEO 地理信息类型:
存储:geoadd key 经度 维度 member 存入用户地理位置
查询:georadius key 经度 维度 距离 查找指定半径内的用户
7.8、Redis中的IO多路复用是怎么回事
**核心:**基于Linux提供的epoll机制完成
IO多路复用:就是用一个线程来管理多个socket(文件描述符),并按需激活线程
epoll内核维护了一个红黑树,来管理所有的socket,并且每个节点都关联了一个事件回调,当系统内核感知到网卡收到数据了,进一步判断这个数据是给哪个socket的,随之调用对应的回调,进一步唤醒线程来处理收到的数据。
7.9、Redis的key的过期删除策略
同时使用惰性过期和定性过期策略
**惰性过期:**在获取某个key时,Redis会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除;
**定性过期:**每隔100ms就随机抽取一定数量的key来检查和删除