/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
Redis 大概是后端开发者绕不开的一个技术。面试要问,项目要用,但很多介绍停留在“内存数据库、单线程、快”这几个标签上。这篇从实际使用角度出发,把 Redis 的核心机制、常见误区和版本演进一次讲清楚。
一、Redis 是什么,解决什么问题
Redis(Remote Dictionary Server)本质上是一个基于内存的键值对存储系统。键只能是字符串,但值支持多种数据结构,这是它区别于普通 KV 缓存的关键。
它的核心价值可以归结为三点:
性能。 数据在内存中操作,命令执行路径短,在常规缓存和计数场景下延迟很低。
数据结构丰富。 不是简单的 key → string,而是提供了 String、List、Hash、Set、ZSet 等结构,能直接在服务端表达去重、排序、队列、对象字段等逻辑,减少应用层的搬运。
能力可扩展。 通过持久化、主从、哨兵、Cluster,Redis 从单机缓存逐步演进为可持久化、高可用、可水平扩展的数据层。
需要提前明确一点:Redis 的“快”和“单线程”经常被放在一起讲,但“单线程”指的是命令执行,网络 I/O 和部分后台任务早已多线程化,后文会单独展开。
术语小注
- 键值对存储:数据以“键 → 值”的形式保存,通过键快速找到值;Redis 的值可以是字符串、列表、哈希、集合等结构,不限于字符串。
- KV 缓存:Key-Value 缓存,通常指值只能是字符串或简单对象的缓存系统。
- 持久化:把内存中的数据写到磁盘,防止进程重启或机器故障后数据全部丢失。
- 主从:一主多从的复制架构,主节点写、从节点读,从节点保存主节点的数据副本。
- 哨兵:独立运行的监控进程,负责发现主节点故障并自动触发主从切换。
- Cluster:Redis 的分布式分片集群方案,把数据分散到多个主节点。
- 水平扩展:通过增加机器或节点来提升总容量和总吞吐,而不是只升级单机硬件。
- 网络 I/O:程序读写网络 socket 的过程,包括接收请求、解析协议、发送响应。
- 命令执行:Redis 真正执行 GET、SET、INCR 等命令的核心环节。
二、五种基础数据类型与选型
Redis 的基础类型各有明确的“形状”,选型的第一步是想清楚数据长什么样。
| String | 二进制安全的字符串、整数或浮点数 | 缓存对象、计数器(INCR)、分布式锁(SET NX) | 大字符串占用连续内存,避免存放过大的 value |
| List | 有序、可重复的双向链表 | 简易消息队列、最新列表、栈/队列 | 作为队列使用时没有消费确认机制,可靠性不如专业消息队列 |
| Hash | 字段-值映射 | 存储对象、配置项,可单独读写某个字段 | 小 Hash 有紧凑编码,字段数或值长度超过阈值后转为哈希表 |
| Set | 无序、不重复 | 去重、共同好友、标签 | 大集合上的交集、并集运算可能产生明显延迟 |
| ZSet | 带分数的有序集合 | 排行榜、延时队列、范围查询 | 分数相同按成员字典序排列;延时队列需业务层处理“到期未消费” |
除了这五种,Redis 还提供 Bitmap(位级统计)、HyperLogLog(基数估算)、Geospatial(地理位置)等特殊结构。8.0 进一步把 JSON、时间序列和概率结构收进核心,后文详述。
选型的关键不是记命令,而是判断数据的“形状”:单个值、列表、对象字段、去重集合,还是需要按分数排序的集合。形状对了,类型自然就对了。
术语小注
- 二进制安全:字符串可以包含任意字节(包括 \\0),按字节长度处理,不会像 C 字符串那样遇到 \\0 就截断。
- INCR:把字符串值当作整数自增 1,常用于计数器。
- SET NX:仅当键不存在时才设置值,常用来实现简单的分布式锁。
- 双向链表:每个元素同时保存前驱和后继指针,支持从两端高效插入和删除;List 的底层实现会随数据量变化。
- 消费确认机制:消费者处理完消息后向队列确认,队列才删除消息;List 没有这个机制,消息取出后若处理失败可能丢失。
- 紧凑编码:小对象使用 listpack、intset 等紧凑结构节省内存;超过阈值后转为哈希表、跳表等常规结构。
- 哈希表:通过哈希函数把字段映射到桶位,支持近似 O(1) 的字段查找。
- 交集、并集:集合运算,分别求两个集合的共同元素和全部元素。
- 字典序:按字节逐个比较的排序方式,ZSet 中分数相同的成员按此顺序排列。
- Bitmap:用二进制位表示状态,适合签到、活跃用户等位级统计。
- HyperLogLog:用固定少量内存估算集合基数(去重后的元素个数),有误差但空间效率极高。
- Geospatial:Redis 的地理位置结构,支持距离计算和范围查询。
- 概率结构:用近似算法换取更低内存的数据结构,结果可能有误差,后文会列出 8.0 新增的几种。
三、持久化:内存数据怎么不丢
Redis 的数据在内存中,进程重启或机器故障就会丢失。持久化负责把数据写到磁盘,核心取舍是数据完整性与恢复速度/写入性能之间。
RDB(快照)
RDB 在指定时间间隔对内存做一次全量快照,生成紧凑的二进制文件。优点是文件小、重启恢复快,适合备份和主从全量同步;缺点是两次快照之间的写入会丢失,数据完整性较弱。
RDB 是 Redis 长期以来的默认持久化方式。SAVE 会阻塞主线程,生产环境通常使用 BGSAVE,由 fork 出的子进程完成快照。
AOF(追加日志)
AOF 以日志形式记录每一条写命令,重启时重放命令来恢复数据。完整性取决于刷盘策略:everysec 下最坏约丢失 1 秒数据,always 理论上不丢但性能代价明显。AOF 文件通常比 RDB 大,恢复时需要逐条重放,速度慢于 RDB。
混合持久化:版本和默认值必须说清楚
混合持久化在 Redis 4.0 引入,5.0 起 aof-use-rdb-preamble 默认值已变为 yes,但真正需要区分的是 7.0 之后的行为变化:从 7.0 开始,多部分 AOF 的基础文件始终使用 RDB 格式,aof-use-rdb-preamble 这个配置项虽然仍被接受,但已不再产生实质影响。换句话说,在 7.0+ 上不需要再纠结这个参数是否开启,混合格式已经是固定行为;而在 4.0–6.x 上,仍然需要确认配置状态。
混合持久化解决的问题是:AOF 重写时,把已有数据以 RDB 格式写入文件头部,后续增量继续以 AOF 命令追加;重启时先快速加载 RDB 段,再重放增量命令,兼顾恢复速度与数据完整性。
一句话选型:能容忍分钟级数据丢失、看重恢复速度和备份效率,RDB 是基础;对数据丢失敏感,开启 AOF 或混合持久化,并按版本确认实际生效的状态。
术语小注
- RDB:Redis Database,把某一时刻的内存数据全量保存成二进制快照文件。
- AOF:Append Only File,把每条写命令追加到日志文件,重启时重放日志恢复数据。
- 快照:某一时刻数据的完整副本,不记录中间变化过程。
- 全量同步:把主节点的完整数据一次性传给从节点。
- SAVE:同步生成 RDB 快照,执行期间会阻塞主线程。
- BGSAVE:后台生成 RDB 快照,主线程继续处理请求。
- fork:创建子进程的系统调用;Redis 利用操作系统的写时复制机制,让子进程在较少内存复制的情况下完成快照。
- 刷盘策略:AOF 把日志写入磁盘的时机,常见有 everysec(每秒刷一次)和 always(每条命令都刷)。
- everysec:每秒把 AOF 缓冲区刷到磁盘,最坏情况下丢失约 1 秒写入。
- always:每条写命令都刷盘,数据最安全但性能开销最大。
- 混合持久化:AOF 重写时,前半部分用 RDB 格式保存全量数据,后半部分继续追加增量写命令。
- aof-use-rdb-preamble:控制 AOF 重写文件是否使用 RDB 格式作为前导的配置项;7.0 之后多部分 AOF 的基础文件固定为 RDB 格式,该配置不再产生实质影响。
- 多部分 AOF:Redis 7.0 引入的 AOF 组织方式,由基础文件、增量文件和清单文件组成。
- AOF 重写:压缩 AOF 日志,把冗余命令合并成能恢复当前数据的最小命令集。
四、高可用:从单机到集群的演进
单机 Redis 有三个天花板:单点故障、内存上限、写吞吐受限于单线程命令执行。高可用方案逐层解决这些问题,不是互相替代的关系。
主从复制
一主多从,主写从读。从节点通过 PSYNC 进行全量或增量同步。它解决了数据备份和读扩展,但主节点故障时仍需要人工介入切换。
哨兵(Sentinel)
哨兵集群监控主从状态,主节点故障时通过主观下线/客观下线判定,触发自动故障转移,将一个从节点提升为主节点。哨兵补上了“自动恢复”这一环,但单机内存上限和写吞吐瓶颈并未改变。
补充一个容易被过度简化的点:Sentinel 的领导者选举使用的是受 Raft 启发的投票机制(Raft-inspired),并非完整实现标准 Raft 协议。它借用了 epoch/任期、每任期一票、多数派等概念,但省略了日志复制和持久化等步骤,选举侧重的是监控状态和配置更新,而非数据复制。了解这一点有助于避免在原理讨论中产生“内置标准 Raft”的歧义。
Cluster 集群:分片解决了什么,又限制了什么
Cluster 是去中心化的分片方案,把整个键空间划分为 16384 个哈希槽,HASH_SLOT = CRC16(key) mod 16384,槽位分配给多个主节点,每个主节点可带从节点。
它同时实现了两件事:数据分片突破单机内存上限,以及写吞吐随主节点数量水平扩展。但这里有一个必须正视的边界:涉及多个 key 的操作在 Cluster 中受槽位限制。
- 事务(MULTI/EXEC)中的所有 key 必须落在同一个槽,否则返回 CROSSSLOT 错误。
- Lua 脚本中访问的所有 key 也必须在同一槽,并且需要通过 KEYS 数组声明。
- MGET、MSET 等多键命令如果跨槽,同样会失败。
解决方案是使用 Hash Tag(如 product:{123}_name 和 product:{123}_price),让相关 key 基于花括号内的内容计算哈希,强制落在同一槽。但低基数或选择不当的 tag 会把数据和流量集中到单个节点,造成严重的数据倾斜和热点瓶颈,需要权衡。
所以更准确的说法是:Cluster 扩展了内存和写吞吐的上限,但代价是多键操作的便利性下降,业务层和客户端需要做适配。
演进逻辑一句话:主从做副本 → 哨兵做自动切换 → Cluster 做分片扩展。每一层解决前一层的遗留问题,同时引入新的约束。
术语小注
- 单点故障:某个关键节点挂掉后,整个服务不可用。
- 内存上限:单机内存有限,数据量超过物理内存后无法继续扩容。
- 写吞吐:单位时间内能处理的写请求数量。
- PSYNC:Redis 主从复制的同步协议,支持全量同步和部分重同步(增量同步)。
- 增量同步:只传输从节点断开期间缺失的写命令,而不是重新传全量数据。
- 读扩展:增加从节点来分担读请求。
- 主观下线:单个 Sentinel 认为某个节点不可达。
- 客观下线:达到法定数量(quorum)的 Sentinel 都认为该节点不可达,才判定为客观下线。
- 故障转移:主节点故障后,把一个从节点提升为新主节点,并让其他从节点跟随新主。
- Raft:一种分布式一致性协议,包含领导者选举、日志复制等步骤;Sentinel 只借鉴了其中的投票和任期思想。
- epoch/任期:类似“届数”的编号,每进行一次新的选举就递增,用于区分不同轮次的投票。
- 多数派:超过一半的参与者同意,投票结果才生效。
- 哈希槽:Cluster 把键空间分成 16384 个槽,每个槽分配给一个主节点,键通过哈希映射到槽。
- CRC16:一种校验算法,Cluster 用它对 key 计算哈希值,再对 16384 取模得到槽号。
- CROSSSLOT:跨槽操作错误;当一条命令涉及的 key 不在同一个槽时返回。
- 事务(MULTI/EXEC):把多条命令打包执行,MULTI 开始、EXEC 提交。
- Lua 脚本:在 Redis 服务端执行的脚本,可原子地执行多条命令;Cluster 中脚本访问的 key 必须同槽。
- KEYS 数组:Lua 脚本中显式声明要访问的 key 列表,Redis 据此判断是否同槽。
- Hash Tag:用花括号 {} 包住 key 的一部分,让这部分内容参与哈希计算,从而使相关 key 落到同一槽。
- 数据倾斜:数据或流量过度集中到少数节点,导致这些节点成为瓶颈。
- 热点瓶颈:某个节点承受了远高于其他节点的请求压力。
五、缓存三大经典问题:穿透、击穿、雪崩
Redis 作为缓存层时,以下三种场景都会让请求绕过缓存冲击数据库,但触发条件不同,方案不能混用。
缓存穿透
查询的数据在缓存和数据库中都不存在,每次请求都打到数据库。典型场景是恶意刷不存在的 ID。
方案:布隆过滤器前置拦截,或缓存空值并设较短 TTL。布隆过滤器的语义需要准确理解:它保证没有漏判(判断“不存在”则一定不存在),但存在可调的误判率(判断“存在”时实际可能不在集合中) 。它适合挡掉大量无效查询,不能当作精确判断使用。
缓存击穿
单个热点键恰好过期,大量并发请求同时回源,瞬间压垮数据库。键本身是真实存在的,问题出在“过期瞬间的并发”。
方案:互斥锁(只放一个线程重建缓存,其余等待),或逻辑过期(键不设物理过期,值里带逻辑过期时间,后台异步更新,读取时先返回旧值)。
缓存雪崩
大量键在同一时间集体过期,或 Redis 实例整体宕机,数据库瞬间失去缓存屏障。
方案:TTL 随机化打散过期时间、多级缓存兜底、限流降级保护数据库。
三者的共同点是“缓存失效”,但穿透失效的是不存在的查询,击穿失效的是单个热点键,雪崩失效的是大面积或全局。用布隆过滤器去防热点键击穿,并不能解决问题——方案混用是常见误区。
术语小注
- 缓存穿透:查询的数据在缓存和数据库中都不存在,缓存无法拦截,请求每次都打到数据库。
- 缓存击穿:某个热点 key 过期瞬间,大量并发请求同时回源数据库。
- 缓存雪崩:大量 key 同时过期,或缓存实例整体不可用,数据库失去缓存保护。
- 布隆过滤器:一种空间效率很高的概率数据结构,能判断“一定不存在”或“可能存在”;没有漏判,但有误判率。
- 漏判:实际存在却被判断为不存在;布隆过滤器不会漏判。
- 误判率:实际不存在却被判断为存在的概率;可通过调整位数组大小和哈希函数数量控制。
- 空值缓存:把“数据库中也不存在”的结果也缓存起来,通常设较短 TTL,防止反复穿透。
- TTL:Time To Live,键的生存时间,到期后自动删除。
- 回源:缓存未命中时,请求转到数据库查询。
- 并发:多个请求在同一时间段内同时到达。
- 互斥锁:同一时刻只允许一个线程重建缓存,其他线程等待或稍后重试。
- 逻辑过期:键不设置物理 TTL,而是在值里记录逻辑过期时间;读取时若逻辑过期,先返回旧值,再由后台异步更新。
- 物理过期:Redis 根据 TTL 真正删除键。
- 旧值:逻辑过期后、新值重建完成前仍可返回的旧数据。
- TTL 随机化:给过期时间加随机偏移,避免大量 key 同一时刻集中过期。
- 多级缓存兜底:本地缓存、分布式缓存等多层缓存配合,某一层失效时仍有其他层挡住请求。
- 限流降级:限制进入数据库的请求量,并暂时关闭非核心功能,保护数据库不被打垮。
- 缓存屏障:缓存层挡住大量请求,使数据库不直接承受全部流量。
六、“Redis 是单线程的”到底怎么理解
这句话需要限定范围才准确。
命令执行始终是单线程的,这是 Redis 原子性保证的基础,也是它不需要复杂锁机制的原因。但“单线程”不等于“只有一个线程在工作”。
Redis 4.0 引入 Lazy Free 机制,通过 UNLINK 命令和后台线程异步释放大 key,避免 DEL 大对象时阻塞主线程。
Redis 6.0 引入网络 I/O 多线程(io-threads),socket 读写和协议解析可以由 I/O 线程分担,但命令执行仍然由主线程串行完成。多线程 I/O 默认不开启,io-threads 默认为 1;官方建议 4 核使用 2–3 个 I/O 线程,8 核使用 6 个,通常不建议超过 8 个。在 6.x/7.x 中,读操作的多线程化还需要额外开启 io-threads-do-reads,默认只对写操作做多线程。
Redis 8.0 对 I/O 线程做了根本性重构,改为基于事件循环的异步模型。一个关键变化是:io-threads-do-reads 在 8.0 中已不再生效,读写默认都由 I/O 线程处理。如果你从 6.x/7.x 升级上来,不能再通过这个参数来控制是否多线程化读操作——行为已经变了。但命令执行的单线程原子性没有改变,官方多核吞吐提升数据(io-threads 设为 8 时最高 112%)也明确注明取决于具体执行的命令。
准确的说法是:Redis 的核心命令处理是单线程的,网络 I/O 在 6.0 之后逐步多线程化,8.0 进一步改变了读写线程的默认行为。 把“单线程”当成“完全单线程”,会错过这些版本之间的实际差异。
术语小注
- 原子性:一个操作要么全部完成,要么完全不发生,中间不会被其他命令插入。
- Lazy Free:延迟释放机制,把大 key 的删除放到后台线程,避免主线程长时间阻塞。
- UNLINK:非阻塞删除命令,先解除键的引用,再由后台线程真正释放内存。
- 大 key:值很大或集合元素很多的键,删除或读写时容易造成阻塞。
- DEL:同步删除命令,删除大对象时可能阻塞主线程。
- 阻塞:主线程被耗时操作占住,无法及时处理其他请求。
- io-threads:Redis 6.0 引入的配置项,指定用于网络 I/O 的线程数;默认为 1,即不开启多线程 I/O。
- io-threads-do-reads:6.x/7.x 中控制是否让 I/O 线程处理读操作的配置项;8.0 的新 I/O 模型下已不再生效。
- 事件循环:一种异步编程模型,通过循环监听事件并回调处理,避免为每个连接创建独立线程。
- 异步模型:发起操作后不立即等待结果,而是继续处理其他任务,结果就绪后再处理。
- 串行完成:命令按顺序一条一条执行,不会并行执行多条命令。
- 多核:CPU 有多个核心,可同时执行多个线程;I/O 多线程利用多核分担网络读写。
- 吞吐量:单位时间内系统能处理的请求数量。
七、Redis 8.0 的主要变化
Redis 8.0 于 2025 年 5 月正式 GA,是近年变化最大的一次版本更新。
“One Redis”:模块不再需要单独安装
此前 RediSearch、RedisJSON、RedisTimeSeries、RedisBloom 等能力需要以模块形式单独部署和版本对齐。8.0 把这些能力合并进 Redis Open Source 核心分发,社区版从“Redis Community Edition”更名为“Redis Open Source”。对使用者最直接的好处是减少了模块版本匹配的运维负担。
新增 8 种数据结构
8.0 新增了 JSON、时间序列、向量集合(beta),以及 Bloom filter、Cuckoo filter、Count-min sketch、Top-k、t-digest 五种概率结构。
向量集合(Vector Set) 值得单独提一句:它受 ZSet 的启发,把“按分数排序”扩展为“按高维向量相似度查询”,面向语义搜索和推荐系统等 AI 场景。它在 8.0 中处于 beta 状态,官方明确表示未来版本可能调整甚至破坏其 API,用于生产前需要关注这一状态。
性能提升:数字要带上条件
Redis 8.0 的官方性能口径是:超过 30 项性能优化,包括命令速度最高提升 87%、吞吐量最高提升至 2 倍、复制速度最高提升 18%,Query Engine 查询处理能力最高可达此前的 16 倍。
延迟方面,在对比 Redis 7.2.5 的 149 项基准测试中,90 条命令的 p50 延迟降低,降幅范围 5.4%–87.4%,中位数 16.7% 。按命令组公布的 p50 延迟最大改善幅度包括:BITMAP 87%、SET 72%、SORTED-SET 61% 等。需要强调:这些是各命令组内的峰值,不等于该组内每一条命令都能达到同等降幅,也不代表所有使用场景都能复现。
吞吐量的 112% 同样有明确条件:多核 Intel CPU 上 io-threads 设为 8,且取决于具体命令。脱离这些条件引用“翻倍”,就会变成误导。
升级 8.0 时容易被忽略的破坏性变更:ACL 权限范围变化
这一点不涉及缓存机制,但对生产升级来说是实打实的风险。
在 Redis 8 之前,@read、@write 等 ACL 类别不包含 Search、JSON、时间序列和概率结构的命令。从 8.0 开始,这些命令被合并进已有的 ACL 类别。官方明确将这一变化列为 potentially breaking changes 。结果是:
- 原本使用 +@read 的用户,升级后可能自动获得执行 FT.SEARCH 等命令的权限;
- 原本使用 +@write 的用户,可能自动获得 JSON.SET 的权限;
- 反过来,+@all -@write 这类规则覆盖的范围也会发生变化,实际放行的命令集合可能缩小。
建议升级前用 ACL DRYRUN 验证现有规则在新版本下的实际效果,必要时用新增的 @search、@json 等类别做更细粒度的控制。如果你只是把 Redis 当纯缓存用,可能不受影响;但只要用到了自定义 ACL,升级前就值得重新审视一遍规则。
术语小注
- GA:General Availability,正式发布版本,区别于 beta、RC 等预览版本。
- 模块:Redis 的可加载扩展,能以插件形式增加搜索、JSON、时序等能力;8.0 之前需要单独安装和版本对齐。
- Redis Open Source:Redis 8.0 社区版的新名称。
- JSON 结构:Redis 8.0 内置的 JSON 文档存储能力,可对 JSON 字段进行读写和查询。
- 时间序列:按时间顺序存储数值的数据结构,适合监控指标、传感器数据等场景。
- 向量集合(Vector Set):存储高维向量并支持相似度查询的结构,用于语义搜索、推荐等 AI 场景;8.0 中为 beta。
- beta 状态:功能可用但 API 可能变化,官方不保证向后兼容。
- Bloom filter:布隆过滤器,判断元素“一定不存在”或“可能存在”,有误判率、无漏判。
- Cuckoo filter:布谷鸟过滤器,另一种概率过滤器,支持删除操作。
- Count-min sketch:频率估计结构,用少量内存估算元素出现次数。
- Top-k:近似找出出现频率最高的 k 个元素。
- t-digest:分位数估计结构,用少量内存估算百分位数。
- 概率结构:用近似结果换取更低内存的数据结构,结果可能有误差。
- Query Engine:Redis 8.0 中负责查询处理的引擎,覆盖搜索等查询能力。
- p50 延迟:中位数延迟,50% 的请求延迟低于该值;比平均延迟更能反映典型体验。
- 基准测试:在受控条件下对比不同版本性能的测试;数字依赖测试环境和命令组合。
- ACL:Access Control List,访问控制列表,用规则限制用户能执行哪些命令、访问哪些 key。
- @read / @write:ACL 命令类别,分别代表读命令集合和写命令集合。
- FT.SEARCH:RediSearch 提供的搜索命令;8.0 前不属于 @read 类别,8.0 后被并入。
- JSON.SET:RedisJSON 提供的写命令;8.0 前不属于 @write 类别,8.0 后被并入。
- ACL DRYRUN:模拟某个用户执行某条命令,检查 ACL 规则是否允许,用于升级前验证权限变化。
- potentially breaking changes:可能破坏现有行为的变更,升级前需要评估和验证。
- @search / @json:8.0 新增的更细粒度 ACL 类别,可单独控制搜索和 JSON 命令权限。
八、把 Redis 的知识串成一条线
Redis 的知识体系可以沿着一条主线来理解:
用合适的数据结构表达业务 → 用持久化保证数据不丢 → 用主从/哨兵/Cluster 保证服务不死且可扩展 → 用正确的缓存策略防止缓存失效时击穿后端。
8.0 的变化是在这条主线之上,把原本分散的模块能力和 AI 相关数据结构收归核心,让 Redis 的适用范围从“缓存”向实时数据平台延伸。
具体到选型和配置,有几个边界值得反复确认:
- 持久化:7.0 之后不需要再纠结 aof-use-rdb-preamble,混合格式已是多部分 AOF 的固定行为;4.0–6.x 则需要确认该配置的实际状态。
- Cluster:多键操作是否跨槽,是否需要 Hash Tag,以及 Hash Tag 是否会造成数据倾斜,需要在设计阶段就纳入考虑。
- 缓存策略:穿透、击穿、雪崩的方案不能互换,先判断失效的是“不存在的查询”“单个热点键”还是“大面积缓存”。
- 单线程:命令执行是单线程的,但 I/O 多线程行为在 6.0、8.0 之间有实质变化,io-threads-do-reads 在 8.0 已失效。
- 8.0 升级:自定义 ACL 规则需要重新验证,@read/@write 的实际放行范围已经改变。
- 性能数字:任何百分比都带着条件和对比基准,脱离条件引用容易产生误判。
Redis 不难用,但用得准,靠的是对这些边界条件的清楚认知,而不是记住几个标签。
术语小注
- 实时数据平台:不仅做缓存,还承担实时查询、搜索、向量检索等数据服务能力。
- 自定义 ACL 规则:用户自己配置的权限规则,而不是默认的全权限或简单只读规则。
- 实际放行范围:ACL 规则最终允许执行的命令集合;命令被并入新类别后,这个范围可能变化。
- 对比基准:性能数字所对比的版本和测试条件,例如“对比 Redis 7.2.5 的 149 项基准”。
版本适用说明:本文涉及 8.0 性能数据的表述以 Redis 官方对比 7.2.5 的基准为准,具体命令组数据来自公开发布材料;io-threads-do-reads 失效与 ACL 变更属于 8.0 的实际行为变化,升级前建议以所用发行版(Redis Open Source / Redis Cloud / 厂商托管版)的对应版本文档做最终确认。
网硕互联帮助中心





评论前必须登录!
注册