跳到内容

14.2 Redis 命令模型、事务与持久化


元数据卡

  • 前置:14.1 内存优先数据库
  • 关键词:Redis、原子命令、MULTI/EXEC、WATCH、RDB、AOF、复制
  • 代码语言:Redis CLI

Redis 的优势来自“围绕数据结构设计命令”,不是把关系表搬进内存。String、Hash、List、Set、Sorted Set、Stream 等类型各自提供原子操作;选错结构会同时伤害内存、延迟和可维护性。

优先用原子命令,不要读—改—写

text
INCR item:42:view_count
HINCRBY item:42 stock -1
ZINCRBY ranking 15 player:7

这些操作在命令边界上原子执行。若客户端先 GET、在本地计算、再 SET,多个客户端就可能覆盖彼此结果。

Redis 的命令执行从客户端视角大体是串行的,但现代 Redis 还使用后台线程、I/O 线程、子进程等完成其他工作。准确说法是“多数命令的核心数据结构操作在主执行线程上完成”,而不是“整个 Redis 只有一个线程”。慢命令、过大的 key 或 Lua 脚本仍可能拖住其他请求。

MULTI/EXEC 不是关系数据库事务

text
MULTI
DECRBY item:42:stock 1
INCR order:created
EXEC

MULTI 之后命令先排队,EXEC 时连续执行,不会与其他客户端命令交错。但它没有关系数据库式的自动回滚:某条命令在执行期因类型等原因失败,队列中其他命令仍可执行。

需要条件更新时,用 WATCH 做乐观检查:

text
WATCH item:42:stock
GET item:42:stock

MULTI
DECRBY item:42:stock 1
EXEC

若受监视 key 在 WATCH 后被改动,EXEC 返回空结果,客户端必须重新读取、重新判断并有界重试。对多步校验更适合用服务端 Lua/Functions 把逻辑压缩成一次原子执行,但脚本也应短小并限制输入规模。

RDB:时间点快照

RDB 周期性生成数据集的紧凑快照。通常由子进程写临时文件,再原子替换旧快照,父进程继续服务;写时复制让父子初始共享内存页。

它的主要取舍:

  • 文件紧凑,备份和大数据集重启通常较快;
  • 两次快照之间的写入可能在故障中丢失;
  • fork() 本身可能造成延迟,写密集期间 COW 会增加内存占用;
  • RDB 文件仍需复制到独立故障域,单机文件不是灾备。

不能机械地说峰值内存“一定翻倍”,实际取决于快照期间被改写的内存页比例、分配器和内核行为;容量规划应以压测峰值为准。

AOF:记录写命令并按策略刷盘

AOF 记录修改数据集的命令,重启时重放。appendfsync 的常见策略:

策略确认路径典型数据窗口
always每批写入都请求 fsync 后确认最小,但仍受硬件和故障模型约束
everysec后台大致每秒 fsync故障时可能丢失最近约一秒写入
no交给操作系统刷新窗口由操作系统策略决定

AOF 会增长,需要重写为能重建当前状态的更短表示。Redis 7 起采用 multi-part AOF:base 文件、一个或多个 incremental 文件及 manifest 共同描述有效日志集合。旧稿只写“一个 AOF 文件被换掉”已经不够准确。

同时启用 AOF 与 RDB

两者可以同时启用;重启时 Redis 会优先用信息更完整的 AOF 恢复。AOF base 可以使用 RDB 格式,这与“同时保存独立 RDB 快照用于备份”不是同一个概念。

持久化配置应从业务容忍度倒推:

  • 纯可重建缓存可关闭持久化,但要验证缓存全失时数据库能否承受回源;
  • 可接受秒级窗口时可评估 AOF everysec
  • 高价值权威数据还需要复制、备份、恢复演练和幂等写入,不能只靠 AOF;
  • WAIT 能等待副本确认,却不会自动把 Redis 变成强一致 CP 数据库,故障切换仍可能受持久化与复制配置影响。

淘汰与持久化是两条轴

maxmemory-policy 决定内存达到上限时淘汰哪些 key;RDB/AOF 决定如何恢复已存在的数据。一个作为权威存储的实例若允许淘汰业务数据,即使 AOF 每次刷盘,也可能把淘汰操作忠实持久化。

因此必须明确实例角色:

  • 缓存:允许淘汰,源数据可重建;
  • 会话或队列:需要定义丢失、重复和过期语义;
  • 权威状态:通常不允许任意淘汰,并需要比单节点持久化更完整的可靠性设计。

运维检查

text
INFO persistence
INFO memory
SLOWLOG GET 20
LATENCY DOCTOR

关注最近 RDB/AOF 状态、重写是否卡住、fork/COW 内存、内存碎片、慢命令和主从延迟。恢复演练时要实际从备份启动新实例并校验 key 数、关键业务对象和应用读写,而不是只检查文件存在。

参考

完成这一章后,应能把“内存快”拆成数据布局、执行模型、持久化确认和恢复预算四个可验证问题。

Built with VitePress | Software Systems Atlas