Redis 是什么?核心优势是什么?
Redis 是基于内存的键值对数据库,支持多种数据结构。
核心优势:
- 高性能(纯内存操作,单线程模型);
- 高可用(主从、哨兵、集群);
- 功能丰富(缓存、分布式锁、消息队列都能做);
- 支持持久化,数据不丢
Redis 使用
redis是一个非关系型数据库,项目中主要是用来存储热点数据,减轻数据库压力
应用场景:缓存、消息队列、实时排行榜、分布式锁、计数器等
Redis 支持哪些数据类型?各自典型场景?
String:缓存、计数器、分布式锁(setnx);
Hash:存储对象(比如用户信息),节省内存;
List:消息队列、最新列表(比如朋友圈动态);
Set:去重、抽奖、交集并集(比如共同好友);
ZSet:排序场景(比如排行榜、延时队列);
补充:还有 Bitmap(布隆过滤器)、Geo(地理位置)等扩展类型。
Redis 为什么这么快?
核心原因:
- 纯内存操作,避免磁盘 IO;
- 单线程模型,无线程切换、锁竞争开销;
- 用 IO 多路复用(epoll)处理网络请求,高效管理连接;
- 数据结构优化(比如跳表、压缩列表)。
Redis 持久化有哪两种方式?区别是什么?
RDB:快照持久化,定时把内存数据快照保存到磁盘;优点是恢复快,缺点是可能丢数据;
AOF:日志持久化,记录所有写命令,重启时重放命令恢复;优点是数据更安全,缺点是文件大、恢复慢;
生产常用:RDB+AOF 混合,兼顾性能和数据安全。
Redis 缓存穿透、缓存击穿、缓存雪崩是什么?怎么解决?
缓存穿透:请求不存在的 key,每次都查数据库;解决:布隆过滤器拦截、空值缓存;
缓存击穿:热点 key 过期,大量请求打数据库;解决:热点 key 永不过期、互斥锁;
缓存雪崩:大量 key 同时过期,数据库扛不住;解决:过期时间加随机值、集群部署、限流降级。
Redis 出现内存泄漏怎么排查?
① 用info memory查看内存使用情况;
② 用redis-cli –bigkeys找出大 key;
③ 检查过期键策略,是否有大量过期键没删除;
④ 检查业务代码,是否有大量无用 key 没清理。
Redis 事务如何保证原子性?
Redis 事务不支持回滚,核心是通过一次性执行、命令队列化、错误处理机制实现弱原子性
弱原子性:要么队列中所有命令都执行,要么都不执行;但执行过程中若出现运行时错误(如对字符串做自增),错误命令会失败,其他命令仍会执行,不会回滚。
而 MySQL 是强原子性:一个语句失败,整个事务回滚,所有操作恢复原状。
Redis 是否支持回滚?
不支持传统回滚:Redis 事务不提供 ROLLBACK,若某条命令失败,后续命令仍会执行。
替代方案:通过乐观锁(WATCH)或 Lua 脚本实现原子性操作
如何用 Redis 实现分布式锁
- Redisson 分布式锁 + Redis 操作(项目主流方案,你高频使用)
核心原理:用 Redisson 实现 Redis 分布式锁,先加锁再执行所有 Redis 操作,保证同一时间只有一个客户端操作该 key,从根本上避免并发和原子性问题;
优势:实现简单,高并发下性能稳定,适配你 500+QPS 的库存扣减场景。 - 使用 Lua 脚本(Redis 原子性最优方案,企业高级用法)
核心原理:Redis 会一次性执行整个 Lua 脚本,执行过程中不会被其他命令打断,天然保证原子性;可在脚本中做逻辑判断 + 多命令执行,甚至实现错误回滚(通过代码逻辑);
优势:原子性最强,减少网络请求(一次脚本执行替代多次 Redis 命令),高并发下性能最优。
Redis 过期键的删除策略?
三种策略:
- 惰性删除:访问时才检查是否过期,过期则删除(节省 CPU,可能内存泄漏);
- 定期删除:每隔一段时间,随机抽查部分过期键删除(平衡 CPU 和内存);
- Redis 用 “惰性删除 + 定期删除” 结合,配合内存淘汰策略兜底。
Redis 管道(pipeline)的作用?原理?
作用:批量发送命令,减少网络往返次数,提升并发;
原理:客户端把多个命令打包发送,Redis 一次性执行,批量返回结果(注意:pipeline 不是原子操作)
如何保证缓存和数据库的数据一致性?
核心原则:最终一致性,常用方案:
- 先更数据库,再删缓存(避免并发问题);
- 缓存删除失败则重试(比如用 MQ);
- 读多写少场景:加延迟双删(删缓存→更数据库→延迟 1s 再删缓存)。
如何优化 Redis 性能?
- 用批量操作(pipeline)减少网络请求;
- 避免大 key(拆分大 key,比如大 Hash 拆成多个小 Hash);
- 合理设置过期时间,避免内存浪费;
- 开启持久化优化(比如 AOF 重写、RDB 定时调整);
- 集群部署,分摊压力。
数据结构类(高频加分项)
- String 底层实现?
底层是简单动态字符串(SDS),和 Java String 区别:① 可修改;② 预分配空间,减少扩容开销;③ 记录长度,获取长度 O (1)。
小字符串用 embstr 编码,大字符串用 raw 编码。 - Hash 底层实现?
小哈希:压缩列表(ziplist),节省内存;
大哈希:哈希表(hashtable),查询更快;
触发切换的条件:哈希元素数超过阈值,或单个元素值过大。 - ZSet 底层实现?
小 ZSet:压缩列表;
大 ZSet:跳表(skiplist)+ 哈希表;
跳表优势:插入、删除、查询都是 O (logN),比红黑树实现简单。
Redis集群
主从复制集群
主节点(master)写数据,从节点(slave)读数据,实现读写分离,提升读的并发能力;
主节点故障后可手动切换到从节点,是哨兵 / 分片集群的基础
- 核心角色
主节点(Master):唯一可写节点,处理所有写请求
从节点(Slave):只读节点,同步主节点数据,处理所有读请求 - 项目适配场景
读多写少,可采用主从集群:主节点处理缓存更新(写),从节点处理查询(读),提升读并发能力;
缺点:主节点故障后需手动切换,无法自动容灾,适合中小规模项目
Redis 主从复制原理?
- 从库连接主库,发送 SYNC 命令;
- 主库执行 bgsave 生成 RDB 文件,同时记录新的写命令;
- 主库把 RDB 文件和新命令发给从库;
- 从库加载 RDB,执行新命令,和主库数据同步;
- 后续主库有写操作,实时同步给从库(增量复制)。
哨兵模式集群(主从 + 哨兵,自动容灾,企业主流)
在主从复制基础上,增加哨兵节点(Sentinel),实现主节点故障自动切换(无需人工干预),解决主从集群的单点故障问题,是企业中读多写少、数据量适中场景的首选
- 核心角色
主 / 从节点:和主从集群一致,负责数据存储和读写分离;
哨兵节点:监控主从节点状态,主节点故障时自动将最优从节点升级为主节点,并通知其他从节点同步新主节点,同时通知业务系统(如你的 Spring Boot 项目)更新 Redis 地址。 - 项目适配场景
哨兵模式:既实现读写分离提升性能,又能自动容灾,主节点故障后秒级切换,保证库存服务不中断;
缺点:所有节点存储全量数据,无法解决海量数据存储问题(如单节点内存不足)。 - 项目对接技巧(你的 Spring Boot 项目如何连接哨兵集群)
无需配置具体 Redis 主从地址,直接配置哨兵地址,Spring Boot 会自动从哨兵获取主节点地址,故障切换后自动更新:
Redis 哨兵(Sentinel)的作用?核心流程?
哨兵是监控 Redis 集群的工具,核心作用:
- 监控主从节点是否存活;
- 主库故障时自动切换(选新主库);
- 通知客户端主库地址变更。
核心流程:主库宕机→哨兵集群投票→选一个从库升主→其他从库同步新主→通知客户端。
分片集群(Redis Cluster,海量数据 + 高并发,大型微服务项目)
哨兵模式的全量数据存储问题,将海量数据分片存储到不同主节点,每个主节点只存储部分数据,同时搭配从节点实现高可用,支持水平扩容(新增节点即可扩容),适合数据量巨大、读写并发极高的微服务项目
- 核心特性
分片规则:采用哈希槽(Hash Slot) 机制,Redis 集群共有16384 个哈希槽,每个主节点分配部分槽位,数据根据key的哈希值映射到对应槽位的节点;
节点角色:至少3 主 3 从(6 节点),每个主节点对应 1 个从节点,主节点负责写 + 槽位管理,从节点负责读 + 容灾;
自动容灾:主节点故障时,其从节点自动升级为主节点,接管槽位;
无中心节点:所有节点平等,可互相通信,客户端连接任意节点即可访问全集群数据
Redis 分片集群(Cluster)原理?如何分片?
- 采用哈希槽(16384 个)分片,槽位 = CRC16(key) % 16384;
- 每个节点负责一部分槽位,数据按槽位分布;
- 主从复制:每个主节点有从节点,故障时从节点升主;
- 客户端请求时,先定位槽位对应的节点,再发请求。
Redis 三种集群的区别及适用场景
开发中常用 Redis 主从、哨兵、分片三种集群:
- 主从集群是基础,实现读写分离,提升读并发,但主节点故障需手动切换,适合中小规模读多写少场景;
- 哨兵模式基于主从,增加哨兵实现主节点故障自动切换,解决单点故障,是企业主流,保证核心业务高可用;
- 分片集群采用哈希槽机制,将数据分片存储,支持海量数据和水平扩容,解决单节点内存瓶颈,缺点是不支持跨槽位多 key 操作。
Redis 集群扩容怎么做?
① 新增节点,加入集群;
② 迁移哈希槽(把旧节点的槽位迁移到新节点);
③ 迁移过程中,Redis 会自动处理请求,不影响业务(无缝扩容)。
Redis集群实战避坑(你项目中踩过的坑 / 注意事项)
生产环境必开持久化:开启 AOF+RDB 混合持久化,防止集群故障导致数据丢失;
节点密码统一:所有主从 / 哨兵 / 分片节点密码必须一致,否则同步 / 监控失败;
禁止单服务器模拟集群:生产环境必须用独立服务器,单服务器多端口模拟会因服务器故障导致整个集群瘫痪;
分片集群 key 设计:若需多 key 操作,用哈希标签(如{user}_1、{user}_2)让多个 key 映射到同一槽位;
监控与扩容:生产环境用 Redis-Exporter+Prometheus 监控集群状态,分片集群通过redis-cli –cluster add-node实现无缝扩容。
基础配置:关闭防火墙 / 开放 Redis 端口(6379 / 哨兵 26379)、禁用透明大页、配置内核参数;所有节点密码统一,开启AOF+RDB 混合持久化(防止数据丢失,贴合你库存 / 课程数据核心场景)。
Redis集群如何搭建
服务器环境:CentOS7/8 Linux 服务器,哨兵模式至少 2 台(1 主 1 从 + 哨兵),分片集群建议 6 台(3 主 3 从,企业标配);Redis 版本选 5.0+(你项目中主流稳定版)。
基础配置:关闭防火墙 / 开放 Redis 端口(6379 / 哨兵 26379)、禁用透明大页、配置内核参数;所有节点密码统一,开启AOF+RDB 混合持久化(防止数据丢失,贴合你库存 / 课程数据核心场景)。
项目适配:哨兵模式用于航天云膜库存扣减、分布式锁、双缓存比对等核心高可用场景;分片集群用于青松职考 10 万 + 课程数据索引、元数据集成平台日均 10 万 + 数据存储等海量数据场景。