Redis 从入门到精通(十四):Redis 7.x 新特性全解 —— 系列收官之作
一、版本演进速览
Redis 5.0 (2018.10): Stream 类型、ZPOPMIN/ZPOPMAX Redis 6.0 (2020.04): ACL 2.0、多线程 I/O、TLS、RESP3 Redis 7.0 (2022.04): Multi-Part AOF、listpack 全面替代、Redis Function、ACL 增强 Redis 7.2 (2023.08): 扩展 listpack 覆盖范围、优化内存效率 Redis 7.4 (2024.07): Hash 过期、更优的内存效率二、Multi-Part AOF:持久化架构重构
这是 Redis 7.0 最重要的改进之一,第三篇已经详细讲过,这里做总结。
2.1 旧版 AOF 的问题
- 重写时一个巨大的内存缓冲区
aof_rewrite_buf,高并发下可能 OOM - 单一 AOF 文件,重写失败时状态不明确
- 文件过大时需要手动 BGREWRITEAOF
2.2 Multi-Part AOF 的改进
# 新架构的文件结构appendonlydir/ ├── appendonly.aof.manifest# 清单文件(总指挥)├── appendonly.aof.1.base.rdb# Base:RDB 格式的全量快照├── appendonly.aof.1.incr.aof# Incremental:增量 AOF└── appendonly.aof.2.incr.aof# 下一个增量文件核心优势:
| 改进点 | 旧版 | Redis 7.0 |
|---|---|---|
| 重写缓冲区 | 单一大内存缓冲 | 直接写入新的 incr 文件 |
| 增量文件轮转 | 不支持 | 达到阈值自动切新文件 |
| 磁盘空间回收 | 重写后才删旧文件 | 渐进式清理历史文件 |
| 恢复灵活性 | 全有或全无 | 可按 manifest 选择性恢复 |
三、Listpack 全面替代 Ziplist
第二篇详细讲过两者的实现差异,这里聚焦于 Redis 7.x 的迁移进展。
3.1 替代时间线
| 版本 | 进展 |
|---|---|
| Redis 5.0 | listpack 首次引入,仅用于 Stream |
| Redis 7.0 | Hash、ZSet 的小数据编码默认使用 listpack |
| Redis 7.2 | listpack 覆盖范围进一步扩大 |
| Redis 7.4 | ziplist 相关配置项几乎全部移除 |
3.2 迁移配置
# Redis 7.0 的新配置(替代旧的 ziplist 配置)hash-max-listpack-entries512# 替代 hash-max-ziplist-entrieshash-max-listpack-value64# 替代 hash-max-ziplist-valuezset-max-listpack-entries128# 替代 zset-max-ziplist-entrieszset-max-listpack-value64# 替代 zset-max-ziplist-value# 升级到 Redis 7.2+ 后,旧的 ziplist 配置自动忽略3.3 为什么一定要换?
连锁更新问题是 ziplist 的致命缺陷(第二篇第四节的完整推演),listpack 通过去掉prevlen字段彻底消除。在高并发写入场景下,ziplist 的连锁更新可能导致毫秒级甚至秒级的延迟抖动——listpack 完全没有这个问题。
四、Redis Function:Lua 脚本的下一代方案
第八篇介绍了 Lua 脚本和 Redis Function 的区别,这里深入。
4.1 Function vs Lua 脚本
# 传统 Lua 脚本EVAL"return redis.call('GET', KEYS[1])"1mykey# 问题:脚本内容每次传输,SHA1 不可读,重启后缓存丢失# Redis FunctionFUNCTION LOAD"#!lua name=mylib redis.register_function('my_get', function(keys, args) return redis.call('GET', keys[1]) end)"FCALL my_get1mykey# 优势:函数名可读,可持久化,管理方便# 查看函数库FUNCTION LIST# 导出函数库FUNCTION DUMP# 恢复函数库FUNCTION RESTORE<serialized># 删除函数库FUNCTION DELETE mylib# 查看函数库统计FUNCTION STATS4.2 Function 的持久化优势
| 特性 | Lua 脚本 | Redis Function |
|---|---|---|
| 重启后 | 脚本缓存丢失,需重新 SCRIPT LOAD | 函数随 AOF/RDB 持久化,重启后自动恢复 |
| 主从复制 | 脚本内容复制到从库 | 函数定义复制到从库 |
| 管理方式 | SHA1 哈希(不可读) | 函数名(可读) |
| 库组织 | 无 | 函数库(library)组织 |
| RESP3 | 不感知 | 可返回 RESP3 类型 Map/Set |
五、ACL 增强
5.1 ACL 2.0 核心功能
# 创建用户:精细的权限控制ACL SETUSER app_user on>password123\~app:*\# 只能操作 app:* 前缀的 key+@read\# 允许读命令+@hash\# 允许 Hash 命令-@write\# 禁止写命令-@dangerous# 禁止危险命令# 通道权限(Pub/Sub)ACL SETUSER subscriber on>pass\&channel:*# 只能订阅特定频道# 选择器(Selector):多规则组合ACL SETUSER power_user on>pass\(~app:* +@all)\# Selector 1: 对 app:* 有全部权限(~cache:* +@read)# Selector 2: 对 cache:* 只有读权限5.2 ACL 日志
# 查看被拒绝的命令ACL LOG10# 重置 ACL 日志ACL LOG RESET# 输出# 1) 1) "count" # 拒绝次数# 2) "reason" # 拒绝原因# 3) "context" # 上下文# 4) "username" # 用户# 5) "client-info" # 客户端信息5.3 最佳实践
# 1. 禁用 default 用户ACL SETUSER default off# 2. 最小权限原则ACL SETUSER app on>pass ~app:* +@read +@write -@dangerous# 3. 定期审计ACL LIST ACL LOG100# 4. 保存配置ACL SAVE六、性能和命令变更
6.1 性能提升
| 优化项 | 版本 | 效果 |
|---|---|---|
| 多线程 I/O | 6.0+ | 网络读写多线程,命令执行仍单线程。io-threads 4 |
| dict 内存优化 | 7.0 | 哈希表内存占用降低约 20% |
| SDS 头优化 | 7.0 | embstr 阈值从 44 字节提升到 44 字节(jemalloc 优化) |
| String 整数编码 | 7.0 | 整数的编码和操作更快 |
| listpack 替代 ziplist | 7.0/7.2 | 消除连锁更新,延迟更稳定 |
6.2 新增命令
# Redis 7.0 新增SINTERCARD numkeys key[key...][LIMIT limit]# 交集数量(不返回具体元素)ZINTERCARD numkeys key[key...][LIMIT limit]# ZSet 交集数量EXPIRETIME key# 获取过期时间(Unix 时间戳,秒)PEXPIRETIME key# 同上,毫秒SORT_RO key[BY...]# 排序(只读,不修改原 key)# Redis 7.2 新增WAIT replicatestimeout# 等待指定数量从库确认(同步复制)# Redis 7.4 新增HEXPIRE key seconds[NX|XX|GT|LT]FIELDS num field[field...]HPEXPIRE key ms[NX|XX|GT|LT]FIELDS num field[field...]HEXPIRETIME key FIELDS num field[field...]HTTL key FIELDS num field[field...]6.3 重点新命令详解
# HEXPIRE: Hash 字段级别过期(7.4 重大更新!)HSET user:session:1001 token"abc"user_id"1001"HEXPIRE user:session:10013600FIELDS1token# 只有 token 字段会过期,user_id 不设过期# SINTERCARD: 高效统计交集数量# 旧方式:SINTER set1 set2 → SMEMBERS → 数数量(O(N+M+K))# 新方式:SINTERCARD 2 set1 set2(O(N+M) 且不传输完整数据)SADD set1 a b c d e SADD set2 c d e f g SINTERCARD2set1 set2# 返回 3(c,d,e)SINTERCARD2set1 set2 LIMIT2# 返回 2(只要够 2 个就停止)# SORT_RO: 只读排序SADD numbers303221SORT_RO numbers BY * LIMIT02ASC# 返回 [1, 3],原 key 不变七、升级建议
7.1 版本推荐
| 当前版本 | 推荐目标 | 理由 |
|---|---|---|
| Redis 5.x | 7.0 | 跨越式升级,获得 Stream + ACL + Function |
| Redis 6.0 | 7.0 / 7.2 | 7.0 稳定,7.2 最新优化 |
| Redis 6.2 | 7.2 | 生产验证充分,listpack 覆盖更广 |
| 新项目 | 7.2 或最新稳定版 | 直接上最新 |
7.2 升级前检查清单
# 1. 检查废弃配置# ziplist 相关配置改为 listpack# 旧的 RDB/AOF 文件格式兼容# 2. 检查命令兼容性redis-cli--clustercheck# 集群模式INFO replication# 主从状态# 3. 滚动升级(Cluster / Sentinel)# 先升级从库 → 故障转移 → 升级旧主库# 逐个操作,不可全部同时升级# 4. 监控观察# 升级后观察 24 小时:内存、延迟、慢查询、主从同步八、系列总回顾
经过十四篇文章,我们构建了完整的 Redis 知识体系:
十四篇文章,四个层次:
| 层次 | 篇目 | 核心收获 |
|---|---|---|
| 基础 | 1-2 | 五种类型 + 六大底层结构,理解 Redis “怎么存” |
| 基础设施 | 3-6 | 持久化 → 主从 → Sentinel → Cluster,“越来越稳” |
| 业务应用 | 7-9 | 缓存设计 + 原子操作 + 分布式锁,“从能用到好用” |
| 进阶运维 | 10-14 | 高级特性 + 客户端 + 实战 + 运维 + 新版本 |
本系列到此完结。从第一篇的
SET key value到最后一篇的Multi-Part AOF和Redis Function,我们走完了 Redis 从入门到精通的全过程。希望这十四篇文章成为你面试复习的知识图谱、生产排障的参考手册、系统设计的灵感来源。感谢阅读。如有疑问或建议,欢迎在每篇文章下方评论交流。