Redis 进阶速查
数据结构与选型、RDB/AOF 持久化、主从与哨兵、Cluster 集群、内存与淘汰、性能调优:Redis 进阶运维速查。
数据结构与选型
五种结构与典型业务场景选型
分布式锁:SET NX PX 与安全释放
加锁用 SET key value NX PX ttl 一步完成(原子),value 用唯一标识(如 UUID 加线程号);释放时必须校验持有者,避免误删他人锁。
Cache Aside:旁路缓存的读写顺序
读路径先查缓存,未命中回源数据库并写回缓存;写路径先更新数据库再删除缓存(而不是更新缓存),删除失败要有重试兜底。
ZSet 排行榜:排名分页与同分处理
用分数排序实现排行榜:ZREVRANGE 取前 N、ZREVRANK 查个人名次;同分时按成员字典序排列,需要更细的先后顺序时把时间戳编进分数。
Bitmap 位图签到与活跃标记
字符串按位寻址:SETBIT 标记、GETBIT 判断、BITCOUNT 统计,一年签到只需约 46 字节;BITOP 支持日/周/月位图与或运算。
Lua 脚本:原子执行与 EVALSHA
EVAL 在服务端执行 Lua 实现复合原子操作;脚本先 SCRIPT LOAD 拿 SHA 再 EVALSHA,可省去每次传输脚本正文的开销。
ZSet 延时队列:分数存执行时间
把任务的执行时间戳作为 ZSet 分数,轮询 ZRANGEBYSCORE 取出到期任务,用 Lua 保证取出加删除原子,避免多消费者重复领取。
五种结构选型对照表
先按访问模式选结构,再按数据规模评估内存:读取整对象用 Hash、排序榜单用 ZSet、去重集合用 Set、位标记用 Bitmap、消息流用 Stream。
计数器设计:INCR 与热点分摊
INCR/INCRBY 是原子计数基础;单键计数在集群中天然集中在一个分片,高并发计数可拆成多个子键再求和,或改用 Hash 把维度合并进一个键。
滑动窗口限流:ZSet 加 Lua
把请求时间戳作为 ZSet 分数:Lua 内先删除窗口外记录、再统计数量、未超限才写入并返回;整套动作原子完成,避免并发下的计数偏差。
Pub/Sub 与 Stream:消息语义对比
Pub/Sub 是即发即忘的广播,订阅者掉线消息即丢;Stream 持久化每条消息、支持消费组与确认重投,二者按可靠性要求选择。
Hash 编码:listpack 与 hashtable 切换
少量字段的 Hash 用 listpack 紧凑保存,超过 hash-max-listpack-entries(默认 128)或单字段超过 64 字节即转 hashtable,内存与查询特性随之变化。
HyperLogLog 基数统计
用约 12KB 固定内存估算集合基数,标准误差约 0.81%,适合 UV、去重计数等场景;PFADD 写入、PFCOUNT 读取、PFMERGE 合并。
Stream 消费组:XGROUP 与 XREADGROUP
消费组把同一条消息分发给组内多个消费者实现分流:XGROUP CREATE 建组,XREADGROUP 用 > 读新消息,处理完成后 XACK 确认,未确认消息进入 PEL。
缓存穿透:空值缓存与布隆过滤器
查询不存在的数据会每次都打到数据库:把空结果短暂缓存(几十秒),或在入口用布隆过滤器判断键是否可能存在,拦住无效请求。
ZSet 跳表编码与内存拐点
有序集合在元素少且小时用 listpack,超过 zset-max-listpack-entries(默认 128)或成员超过 zset-max-listpack-value(默认 64 字节)后转为 skiplist 与哈希表组合。
Stream 消息写入:XADD 与 ID 规则
Stream 是有序、可持久化、带消费组的消息结构:XADD 生成毫秒时间戳-序号 ID,XRANGE/XREVRANGE 按 ID 范围读取,容量用 MAXLEN/MINID 控制。
GEO 地理检索:GEOADD 与 GEOSEARCH
基于 ZSet 的 GeoHash 实现:GEOADD 写入经纬度,GEOSEARCH 按半径或矩形范围查询并可返回距离与排序,GEOPOS/GEODIST 取坐标与两点距离。
缓存雪崩与 TTL 打散
大批缓存同一时刻失效,请求同时回源可能压垮数据库:给 TTL 加随机抖动、分级过期,或对热点数据做多级缓存与限流预热。
OBJECT ENCODING 查看键的底层编码
读取键当前使用的内部编码(int/embstr/raw、listpack、intset、quicklist、skiplist、hashtable 等),为内存优化与结构选型提供直接依据。
XPENDING 与 XCLAIM 处理未确认消息
XPENDING 查看各消费者的未确认消息数与范围,XCLAIM 把超时未确认的消息转给其他消费者重试,XAUTOCLAIM 可批量认领。
对象缓存:String 存 JSON 与 Hash 的取舍
整对象读写用 String 加 JSON 简单直接;需要频繁更新单字段或字段级原子递增时用 Hash,避免每次读改写整个序列化对象。
热点 Key 击穿:互斥重建与逻辑过期
热点键失效瞬间大量并发回源:用互斥锁保证只有一个请求重建缓存,其余等待或返回旧值;逻辑过期方案让重建异步进行,请求始终拿得到数据。
String 与 SDS 结构:编码差异与内存
String 用 SDS(简单动态字符串)存储,短字符串走 embstr 一次分配,超过 44 字节转 raw 两次分配;整数值直接用 int 编码省内存。
quicklist 与 list-max-listpack-size
List 由 quicklist(多个 listpack 节点组成的双向链表)实现,节点字节上限由 list-max-listpack-size 控制:正数按元素个数,负数按大小(-1=4KB、-2=8KB 依此类推)。
键名设计:分层命名与长度控制
用冒号分层(业务:对象:标识:字段)让检索与批量管理有规律可循;键名本身也占内存,短前缀加紧凑 ID 能省下可观的常驻开销。
Lua 脚本的限制与超时行为
脚本执行期间服务器被独占,默认 lua-time-limit 5 秒只用于打日志;超时后仅允许 SCRIPT KILL(未写数据时)或 SHUTDOWN NOSAVE 中断。
令牌桶限流:Hash 加时间差补桶
用 Hash 保存剩余令牌数与上次补充时间:每次请求按流逝时间补令牌、够则扣减放行;适合允许突发流量的场景。
listpack 紧凑列表结构
listpack 是 7.0 起取代 ziplist 的顺序紧凑结构:整块内存连续存放、头部记录总长,作为小 Hash、小 ZSet 与 quicklist 节点的底层容器。
Stream 容量控制:MAXLEN 与 XTRIM
XADD 时带 MAXLEN 或独立执行 XTRIM,把 Stream 限制在可控长度;加 ~ 表示近似裁剪、更快,不加则精确裁剪。
Hash 字段更新与计数:HINCRBY 家族
HINCRBY 对 Hash 内整数字段原子递增,HINCRBYFLOAT 支持浮点;HSETNX 只在字段不存在时写入,适合初始化标记与幂等处理。
编码阈值调优:先测再调
调优顺序:OBJECT ENCODING 看现状、MEMORY USAGE 量化单键、结合延迟观察后再改阈值;阈值只影响后续触发编码判断的键,存量键需要重写才会转换。
intset 整数集合与 Set 内存
Set 里全是整数且数量不超过 set-max-intset-entries 时用 intset 存储:有序数组加二分查找,内存占用远低于哈希表。
BITFIELD 位域计数器
在字符串上按任意位宽读写整数字段(u8/i16 等),一次调用可执行多条 GET/INCRBY,适合把多个小计数封装进一个键;溢出行为可选 WRAP/SAT/FAIL。
RedisJSON:结构化文档读写
RedisJSON 模块把 JSON 文档存为树结构:JSON.SET 整体写入、JSON.GET 按路径取、JSON.NUMINCRBY 原子更新数值,适合字段级更新频繁的复杂对象。
XAUTOCLAIM:认领超时消息
XAUTOCLAIM 把满足最小空闲时间的 pending 消息转移给当前消费者,用于消费者宕机后的消息回收,可配合 JUSTID 只取 ID。
ZADD 的 GT/LT:条件更新分数
ZADD 支持 GT、LT 修饰符:仅当新分数更大(或更小)时才更新;与 NX/XX 组合可表达「只更新且只在更优时」的语义。
GETDEL 与 GETEX:原子取删与 TTL 维护
GETDEL 取值同时删除(适合一次性令牌),GETEX 取值同时设置或清除 TTL(适合续期场景),都是单命令原子完成。
SINTERCARD:带上限的交集计数
SINTERCARD 只计算多个集合交集基数,可用 LIMIT 提前收敛,避免 SINTERSTORE 生成大结果集的成本。
LMPOP:多键弹出首选非空
LMPOP 从第一个非空的列表弹出元素(可指定方向与数量),把「遍历多个候选键」收敛为单命令,减少多轮试探。
COPY:实例内复制键
COPY 在同实例内复制键(可跨库、可 REPLACE 覆盖),免去客户端序列化往返;注意复制后内存占用增加且集群模式要求同槽。
PFMERGE:合并多个 HyperLogLog
PFMERGE 把多个 HLL 的寄存器合并到目标键,用于跨时间段/维度的去重基数合并;合并结果仍是概率估算,不能还原成员。
SETRANGE:定长字段原位更新
SETRANGE 从指定偏移写入字符串内容,超出长度自动补零扩展;适合定长记录原位更新与位图式编码场景。
持久化
RDB/AOF 配置、恢复与选型
AOF 原理:追加日志与重放
AOF 把每条写命令追加到日志文件,重启时按顺序重放恢复数据;写入先进入内存缓冲,再按 appendfsync 策略刷盘。
RDB 快照原理
RDB 是某一时刻全量数据的二进制快照:fork 出子进程把内存数据序列化写入临时文件,写完原子替换 dump.rdb,主进程全程只负责响应请求。
RDB 与 AOF 对比与混用
RDB 体积小、恢复快、适合备份;AOF 丢失窗口小、适合数据安全要求高的场景,两者可同时开启:AOF 负责近实时恢复,RDB 负责冷备与快速重放。
appendfsync:always/everysec/no
appendfsync 控制刷盘时机:always 每条命令后 fsync(最稳最慢)、everysec 每秒一次(默认,折中)、no 交给操作系统(最快但丢失窗口不可控)。
持久化方案:先定可容忍丢失量
选型从业务能容忍多少数据丢失出发:纯缓存可关持久化;秒级丢失可接受用 AOF everysec;要求更严则评估 always 的写放大与磁盘能力。
fork 与写时复制(COW)机制
fork 瞬间内核复制父进程页表,父子共享物理页;子进程写数据时内核按页复制新副本,父进程继续写自己的新页,旧值保留给快照读取。
从 RDB 恢复数据
恢复步骤:停止实例 → 备份当前文件 → 用目标 dump.rdb 覆盖 dir 下的快照(确认属主权限)→ 启动并核对数据量与抽样键。
appendonly 与 AOF 文件形态
appendonly yes 开启 AOF;7.0 起 AOF 为多文件结构(base 与 incr 片段加 manifest),旧版本为单一 appendonly.aof 文件。
BGREWRITEAOF:AOF 重写
重写由子进程根据当前内存数据生成新 AOF:期间新写入进入重写缓冲,重写完成后追加上缓冲并原子替换旧文件,文件体积随之回落。
SAVE 与 BGSAVE 的区别
SAVE 在服务进程内同步写快照,期间所有请求被阻塞;BGSAVE fork 子进程后台写,主进程继续服务请求。
BGSAVE 失败与写保护
快照失败(磁盘满、权限错误等)时 lastbgsave_status 变为 err;默认 stop-writes-on-bgsave-error yes 会让写请求直接报错,防止继续写入无法持久化的数据。
INFO persistence 常用字段解读
排查持久化状态先看 INFO persistence:rdb_last_save_time、rdb_changes_since_last_save、aof_last_write_status 等字段直接反映最近一次保存与出错情况。
RDB 的触发方式
RDB 快照可由节奏配置自动触发,也可手动 BGSAVE/SAVE,或由 SHUTDOWN、复制全量同步等事件触发。
启动加载:数据库从文件恢复的顺序
重启时 Redis 先按配置判断加载来源:开启 AOF 且文件存在时优先加载 AOF,否则加载 RDB;两者都不存在则以空库启动。
redis-check-aof 修复 AOF
redis-check-aof 校验 AOF 的格式与命令完整性,--fix 会把文件截断到最后一个完整命令并重写,是最常见的 AOF 抢救手段。
save 配置:自动快照节奏
save 行定义触发条件:save <秒> <变更数> 表示在该秒数内写操作达到指定次数就触发快照,多条规则按并集判断,任一满足即触发。
物理备份:定时拷贝快照文件
在 BGSAVE 成功后把 dump.rdb 拷贝到备份目录或对象存储,是成本低、恢复直观的冷备方式;注意文件可能很大且集群需逐节点执行。
vm.overcommit_memory 与后台保存
fork 大实例时父进程可能因内核内存策略拒绝分配,导致 BGSAVE 失败;官方建议设置 vm.overcommit_memory=1,允许内核对 fork 场景的地址空间承诺。
dbfilename 与 dir:数据文件位置
dbfilename 决定 RDB 文件名(默认 dump.rdb),dir 决定工作目录;AOF 文件同样落在 dir 下。修改 dir 后新文件写入新路径,已有文件需先迁移。
自动重写触发条件
auto-aof-rewrite-percentage 与 auto-aof-rewrite-min-size 共同决定是否自动重写:AOF 体积相对上次重写后增长超过百分比,且总大小超过最小阈值时触发。
运行时切换持久化配置
CONFIG SET appendonly yes 会触发基线重写;CONFIG SET save 调整节奏即时生效;改完确认无误后用 CONFIG REWRITE 落到配置文件。
redis-check-rdb 校验快照
redis-check-rdb 工具可解析快照文件、报告版本与键数量,并对损坏位置给出提示,是恢复前验证备份可用性的关键一步。
7.0 多文件 AOF 结构
7.0 起 AOF 目录由 manifest 清单、base 基线文件与 incr 增量文件组成;重写只生成新 base 并切换 manifest,不再重写单个巨型文件。
丢失窗口计算与业务对账
丢失窗口由持久化组合决定:AOF everysec 约 1 秒、按时间快照则等于两次快照间隔内所有写入;把窗口写进业务 SLA 并准备对账与补数方案。
aof-load-truncated:尾部截断处理
断电可能让 AOF 尾部只写了半条命令:aof-load-truncated yes(默认)会加载到最后一个完整命令并记录警告,no 则直接启动失败。
SHUTDOWN 与保存行为
SHUTDOWN 默认在执行前尝试保存数据(取决于持久化配置),成功才退出;SHUTDOWN NOSAVE 强制不保存退出,用于文件已损坏或磁盘异常的抢险场景。
持久化监控指标清单
把持久化健康度纳入监控:最近快照时间与状态、AOF 写状态、重写进行中与耗时、磁盘使用率、fork 耗时、COW 内存增量都要有阈值与告警。
换机迁移:快照加配置的完整流程
迁移流程:老机 BGSAVE 取快照(或等主从追平后提升从库)→ 传送到新机 → 挂载目录改配置启动 → 核对数据与业务冒烟,最后切流量。
禁用自动快照:save 空字符串
设置 save 为空表示关闭自动快照:Redis 不再按节奏触发 BGSAVE,但手动 BGSAVE 与关闭时的保存仍可用(取决于关闭策略)。
透明大页(THP)与 fork 延迟
开启 THP 时 fork 的页表拷贝量成倍放大,延迟显著上升;Redis 官方建议关闭透明大页,降低快照与全量同步时的停顿。
持久化磁盘与文件系统的选择
持久化性能取决于磁盘延迟稳定性:本地 SSD 优于网络盘,fsync 抖动大的存储会让 AOF 每秒刷盘进入长尾;RAID 写缓存策略也会影响落盘确认。
数据安全组合:持久化之外的三层
单机持久化只解决「本机重启不丢」:完整防线是持久化加多副本(主从/集群)加异地备份加恢复演练,任何一层缺失都会让数据暴露在特定故障下。
rdbcompression 与快照体积
rdbcompression 控制快照字符串是否使用 LZF 压缩:默认开启,牺牲少量 CPU 换取明显更小的文件与更快的传输。
RDB 版本兼容与升级回滚
每个版本写入的 RDB 带版本号,旧版本 Redis 不能加载新版本生成的快照;降级回滚前必须用旧版本能识别的快照,或先导出为通用格式。
no-appendfsync-on-rewrite 权衡
重写期间如果仍执行 fsync,磁盘压力大时主线程可能被拖慢;no-appendfsync-on-rewrite yes 在重写期间暂停 fsync 换取延迟,代价是这段窗口内丢失风险上升。
版本升级时的持久化注意点
升级前用 redis-check-rdb/redis-check-aof 校验现有文件,确认备份可加载;升级后观察 aof 相关目录结构变化(7.0 多文件)与加载来源。
AOF 体积增长与磁盘水位
AOF 记录的是命令历史,同键反复修改会不断追加,体积可能远超数据集本身;用重写压缩,并对 AOF 目录设置磁盘水位告警。
rdbchecksum:快照完整性校验
rdbchecksum 默认开启,在 RDB 文件尾部写入 CRC64 校验和;加载时校验不通过会拒绝启动,避免悄悄载入损坏数据。
RDB 会保存 LFU/LRU 元数据
开启 maxmemory 淘汰后,RDB 会记录每个键的空闲时间/频率信息,重启加载后近似恢复,但精度有限:长时间停机后热度信息会失真。
重写缓冲区:衔接新旧文件
重写开始后新写入无法只靠子进程快照覆盖,Redis 把期间的写命令同时追加到重写缓冲,子进程完成后把缓冲合并进新文件,保证不丢中间命令。
fsync 错误与数据安全
Linux 上 fsync 返回错误后,脏页可能已被丢弃:此时继续写入会让「已确认落盘」的假设失效,Redis 检测到写错误会停写并告警,需要人工介入。
恢复演练:备份可用性的唯一证明
定期在独立环境用真实备份恢复并核对数据:加载时间、样本键、业务对账项;演练记录是持久化方案可信度的直接证据。
容器化实例的持久化注意点
容器里数据目录必须挂载持久卷(且卷不由容器生命周期管理);停止容器要留出优雅退出时间,确保 SHUTDOWN 保存流程跑完。
持久化排查工具速查
常用工具与命令:redis-check-rdb、redis-check-aof、INFO persistence、LASTSAVE、DBSIZE 与 DEBUG RELOAD,覆盖校验、状态、计数与自检四类需求。
COW 内存监控方法
快照与重写期间的额外内存来自 COW 复制:对比快照前后 used_memory_rss 与进程 RSS,配合内存余量阈值决定快照窗口。
低峰快照与重写编排
把 BGSAVE 与重写安排在业务低峰:写命令少则 COW 少、fsync 竞争弱,快照完成更快;必要时用定时任务在低峰显式触发。
备份完整性校验:md5 与抽检
备份落地后计算校验和并记录,恢复前重新比对;同时抽检业务键值是否符合预期,双重保证备份既完整又正确。
纯缓存实例的持久化取舍
纯缓存实例可以选择不持久化:省去 fork 与磁盘开销,代价是重启后冷启动回源,需要评估后端数据库能否扛住瞬时压力。
AOF 时间戳注释(7.0)
aof-timestamp-enabled 开启后,AOF 中会按秒插入 #TS 时间戳注释,用 redis-check-aof 或人工回溯时可对照命令发生的大致时间。
备份文件的权限与加密
快照与 AOF 是明文全量数据:备份目录权限收紧(如 700 属主专用)、传输加密、云端存储开启服务端加密,敏感业务必要时先加密再出机房。
增量文件轮转与重写关系
7.0 多文件 AOF 中,重写会生成新的 base 基线并开启新的 incr 增量文件,旧文件在切换完成后被清理,目录始终由 manifest 描述有效集合。
磁盘告警时的应急处置顺序
磁盘接近满:先确认是 AOF 还是快照目录占满 → 立即扩容或清理可安全删除的文件 → 恢复写入 → 安排重写;期间避免让快照持续失败触发写保护。
WAITAOF:等待 AOF 落盘确认
WAITAOF numlocal numreplicas timeout 等待本地 AOF 与副本 AOF 的 fsync 确认,返回已达成的本地与副本数量;用于敏感写入的落地确认。
DEBUG RELOAD 验证落盘数据
DEBUG RELOAD 把内存数据序列化为 RDB 再从磁盘加载回来,常用于验证「当前内存状态落盘后能否完整恢复」,是持久化改动后的自检手段。
快照临时文件与残留处理
快照写入 temp-<pid>.rdb 后再原子替换 dump.rdb;进程被强杀可能残留 temp 文件,一般无害,可确认无对应进程后清理。
manifest 完整性要求
多文件 AOF 的 manifest 记录每个文件类型、序号与文件名:任何增删改名都要同步更新,否则加载直接失败,属于强一致性清单。
主从与哨兵
复制原理、哨兵部署与切换
REPLICAOF 建立主从复制
REPLICAOF host port 让当前实例成为目标实例的从库:会先做一次全量同步,之后持续增量同步;REPLICAOF NO ONE 可解除并提升为主。
哨兵体系与职责
Sentinel 是独立进程集群:监控主从实例、主观/客观判定下线、选举领导者、执行主从切换,并向客户端提供「当前主库地址」的查询入口。
sentinel.conf 部署示例
最小配置只需 monitor 行声明被监控主库与法定票数,其余参数按默认;配置文件路径需要在启动命令中显式指定。
PSYNC:部分重同步机制
PSYNC 让从库断线重连后尽量只同步缺失部分:主库保留复制积压缓冲(backlog),从库上报偏移量,落在缓冲范围内的增量可直接补发。
quorum 与 majority 的区别
quorum 是判定「客观下线」所需的哨兵票数;而执行切换还需要哨兵领导者选举获得多数派(majority)同意,两个门槛可能不同。
全量同步流程与资源消耗
全量同步:主库 fork 生成 RDB 传输给从库,从库清空并加载,期间主库把增量命令写入复制缓冲区,加载完成后补发。
SENTINEL 常用查询子命令
运维排查哨兵先掌握:MASTERS、MASTER、SLAVES、SENTINELS、GET-MASTER-ADDR-BY-NAME、CKQUORUM、IS-MASTER-DOWN-BY-ADDR 等查询类子命令。
复制偏移量与延迟判断
主库 master_repl_offset 与从库 slave_repl_offset 的差值反映复制落后字节数;差值稳定在较小范围说明同步健康。
从库提升与 REPLICAOF NO ONE
计划内切换/提升:在目标从库执行 REPLICAOF NO ONE,使其停止复制成为独立主库;随后把其他从库指向新主库。
down-after-milliseconds:判下限阈值
down-after-milliseconds 决定实例多久无响应被判为主观下线(SDOWN):太敏感会被网络抖动误伤,太迟钝则延长故障窗口。
复制链路认证:masterauth
主库启用密码后,从库必须配置 masterauth(以及 6.0+ 的用户名 masteruser)才能完成握手与同步,否则连接被拒。
SDOWN 与 ODOWN 判定流程
单个哨兵认定失联是主观下线(SDOWN);当达到 quorum 数量的哨兵都报告 SDOWN,状态升级为客观下线(ODOWN),随后才进入领导者选举与切换。
客户端接入哨兵的模式
客户端连接哨兵列表(而非单台哨兵)查询主库地址,并在切换事件/查询变化后刷新连接池;多数主流客户端库内置哨兵支持。
replica-read-only 与从库可写性
replica-read-only yes(默认)让从库拒绝写命令;设为 no 可让从库接受本地写入,但这些数据不会同步到主库,重启全量同步时可能被覆盖。
复制延迟监控与常见原因
延迟常见来源:网络带宽不足、主库大命令(如大 key 删除)、从库加载慢、AOF 重写占用磁盘;用 offset 差、lag 指标与从库日志联合定位。
哨兵访问数据实例的认证
被监控实例设置密码后,哨兵需要 sentinel auth-pass <master-name> <password> 才能连接;6.0+ 支持 sentinel auth-user 指定 ACL 用户。
repl-backlog:积压缓冲的容量与保留
repl-backlog-size 决定主库为断线从库保留多少复制数据;网络抖动大、写入量高的环境需要放大 backlog,从库长期离线则缓冲可释放。
读写分离的客户端路由
主从常用于读写分离:写走主库、读分摊到从库;路由方式有客户端配置、代理(如 VIP 切换、中间件)等,延迟敏感读要评估复制延迟。
monitor 指令与运行时监控变更
sentinel monitor 声明被监控对象;运行时可先用 SENTINEL MONITOR 增加、SENTINEL REMOVE 移除,再 SENTINEL FLUSHCONFIG 落盘。
查询当前主库地址
SENTINEL GET-MASTER-ADDR-BY-NAME <name> 返回当前主库的 ip 与 port,是客户端与运维脚本在切换后重新定位主库的标准入口。
INFO replication 字段速读
该段落的 role、connected_slaves、master_link_status、master_last_io_seconds_ago、slave_repl_offset 等字段,是判断复制拓扑与健康度的主要依据。
FAILOVER 命令:受控切换
6.2 起提供 FAILOVER 命令做协调式切换:主库等待从库追平后提升目标从库并把其他从库指向新主,减少手工步骤与分叉风险。
切换事件与 +switch-master 通知
哨兵通过发布订阅频道 __sentinel__:hello 与事件流通知状态变化,客户端关键关注 +switch-master(新主库地址)与 +sdown/-sdown。
哨兵切换演练方法
演练:停掉主库进程(或在维护窗口执行 SENTINEL FAILOVER),观察哨兵日志、客户端恢复与数据一致性,并记录切换耗时与业务影响。
写保护:min-replicas-to-write
min-replicas-to-write 与 min-replicas-max-lag 组合限制「健康副本不足时拒绝写入」,防止单主孤岛继续接收写入造成数据孤悬。
从库输出缓冲区限制
主库为每个从库维护输出缓冲:慢从库(网络差、处理慢)会让缓冲堆积,超过 client-output-buffer-limit replica 的硬限制时主库会主动断开该从库。
failover-timeout 的作用
failover-timeout 控制切换相关超时:如从「故障确认」到「完成切换」的等待上限、重试间隔等,影响切换节奏与重复切换行为。
哨兵的边界与局限
哨兵解决主从高可用,但扩展性受单主写入限制;同时存在脑裂风险(主库与哨兵间网络割裂时可能双写),需要用写保护和多副本策略缓解。
无盘复制:repl-diskless-sync
无盘复制让主库直接把 RDB 通过网络写给从库,不落地中间文件,适合磁盘紧张或快照慢的场景;repl-diskless-sync-delay 控制等待更多从库加入的窗口。
replica-priority:哨兵选主权重
replica-priority 影响哨兵故障切换时的候选顺序:数值越小优先级越高,0 表示永不被提升(适合只读副本或跨机房备份节点)。
parallel-syncs:同步并发度
parallel-syncs 限制切换后同时向新主库做同步的从库数量:小数值让服务能力渐进恢复,大数值让集群整体更快恢复同步但会加重新主库负载。
repl-timeout 与断连判定
repl-timeout(默认 60 秒)定义主从之间多久没有有效交互判定为断连;网络高延迟或批量同步时过小会误判断连并触发重同步。
WAIT:写入同步确认
WAIT numreplicas timeout 阻塞等待指定数量的副本确认收到此前的写命令,用毫秒级等待把「写已扩散」作为可选保障,返回实际确认数量。
哨兵领导者选举(Raft 思路)
进入 ODOWN 后,哨兵们请求投票选出领导者执行切换:候选按配置纪元递增请求,获得多数派票者当选,未当选者按 failover-timeout 节流重试。
哨兵日志定位问题
sentinel 的关键状态变化全部落日志:+sdown/+odown/+new-epoch/+try-failover/+failover-end/+switch-master,按时间轴读日志是定位切换问题的主线。
replica-serve-stale-data:断链时的读服务
从库与主库断链时,replica-serve-stale-data yes(默认)允许继续用旧数据响应读请求,no 则除 INFO 等少数命令外全部返回错误。
主从故障恢复检查清单
故障恢复时逐项核对:谁是当前主库、各从库复制状态与偏移、是否有双主、数据差异范围、客户端地址是否刷新、告警是否恢复。
replica-announce-ip/port:对外公告地址
NAT 或容器环境中从库实际端口与对外地址不一致时,用 replica-announce-ip/port 公告正确地址,否则主库 INFO 中显示的从库地址不可达。
级联复制:从库再挂从库
从库可以继续作为其他实例的主库(级联/链式复制),减轻顶层主库的同步压力;代价是链路加深后延迟叠加,故障影响面更复杂。
重启后的复制角色保持
role 变化会被写入运行配置:用 REPLICAOF 建立的从库重启后(配置文件中存在 replicaof 时)仍保持从库身份,除非主动解除或配置文件被改。
哨兵公告地址:announce-ip/port
NAT 或容器环境下用 sentinel announce-ip/port 公告哨兵自身可达地址,否则其他哨兵与客户端拿到的地址不可用。
client-reconfig-script:切换后回调
sentinel client-reconfig-script <master> <script> 在切换时调用外部脚本,把新主库地址通过参数传入,可用来更新配置中心或 DNS。
notification-script:状态变化告警
sentinel notification-script <master-name> <script> 在发生重要事件(如切换、下线)时调用脚本,用于对接告警系统等场景。
从库无盘加载
repl-diskless-load 控制从库接收全量同步数据时是否直接写入内存(或先写盘再加载):内存充足时用 swapdb 加速,内存紧张时保持落盘模式。
哨兵端口与 TLS
哨兵默认端口 26379(可通过 port 修改),6.0+ 支持 TLS 保护哨兵与实例、哨兵之间的通信链路。
哨兵运维检查清单
上线与巡检清单:哨兵数量与部署位置、quorum 与 majority、认证配置、公告地址、日志落盘、告警联动、切换演练记录,逐项核对。
复制心跳:repl-ping-replica-period
主库按 repl-ping-replica-period(默认 10 秒)向从库发送 PING,用于从库检测主库存活并触发重连,也是延迟判断的基础心跳。
哨兵与实例的启动顺序
机房整体重启后的启动顺序:先起主库与从库,再起哨兵;哨兵起早了会在实例未就绪时误判并可能触发无意义切换。
复制链路的传输安全
标准复制端口默认明文传输:跨不可信网络需叠加 TLS(6.0+ 的复制与集群总线支持 TLS)或使用专线/VPN 承载复制流量。
resolve-hostnames:主机名支持
7.0 起哨兵与集群支持用主机名替代 IP 配置(resolve-hostnames/announce-hostnames),适合容器与动态 IP 环境。
SENTINEL FLUSHCONFIG:固化配置
SENTINEL FLUSHCONFIG 把运行期变更(如 failover 后的主库地址)写回 sentinel 配置文件;否则重启后可能回到旧配置。
Cluster 集群
分片、槽位迁移与扩容缩容
Redis Cluster 与 16384 槽位
集群把键空间划分为 16384 个槽(slot),每个主节点负责一部分槽;键经 CRC16 取模映射到槽,槽在节点间迁移实现扩容与缩容。
redis-cli --cluster create 创建集群
用 redis-cli --cluster create 一次部署多节点集群:按参数顺序每 N 个节点分配一主一从,--cluster-replicas 指定每个主节点的从节点数量。
MOVED 与 ASK 重定向
槽归他人时返回 MOVED(永久重定向,客户端应刷新路由表);槽正在迁移时返回 ASK(临时重定向,仅本次需对目标节点先发 ASKING)。
CROSSSLOT 错误与多 key 限制
集群模式下多 key 命令(MGET、MSET、SINTERSTORE、事务、Lua)要求所有键在同一槽,否则报 CROSSSLOT Keys in request do not hash to the same slot。
CLUSTER KEYSLOT:键到槽的映射
CLUSTER KEYSLOT key 返回键所属槽号,按 CRC16(key)%16384 计算并遵循哈希标签规则,用于验证路由与排查跨槽问题。
CLUSTER INFO:集群状态速览
CLUSTER INFO 返回 cluster_state、槽统计、节点数、消息统计等:cluster_state:ok 表示所有槽都被正确服务,是集群健康的首要判据。
redis-cli --cluster reshard 迁移槽
reshard 是槽迁移的自动化入口:交互式输入目标槽数与目标节点(或 --from/--to 指定),工具会完成逐键迁移与状态广播。
cluster-enabled:启用集群模式
cluster-enabled yes 打开集群模式,实例启动后进入集群状态;未加入任何节点的实例处于「集群状态不可用」但可执行 CLUSTER MEET 加入。
集群客户端与 redis-cli -c
客户端需支持集群:建立路由表、跟随 MOVED/ASK、感知拓扑变化;redis-cli 用 -c 打开跟随模式便于调试。
CLUSTER NODES:拓扑明细解读
CLUSTER NODES 每行一个节点:节点 ID、地址、flags(master/slave/myself/fail)、主节点、时间戳、纪元、槽分配与连接状态。
CLUSTER SETSLOT 与槽迁移状态机
槽迁移通过三种 SETSLOT 状态推进:目标节点 IMPORTING、源节点 MIGRATING,迁完向所有节点广播 NODE 指定归属,最终槽正式易主。
哈希标签设计实践
花括号内的内容决定槽位:{order}:1001 与 {order}:1002 的标签不同、可能跨槽;{user:1001}:a 与 {user:1001}:b 的标签相同、必然同槽。
CLUSTER FAILOVER:集群受控切换
在从节点执行 CLUSTER FAILOVER 把其主节点降为从节点并接管:默认会等待偏移对齐(优雅切换),FORCE 跳过对齐,TAKEOVER 不做任何协商。
redis-cli --cluster check 健康检查
集群体检命令:输出各节点的槽覆盖、从节点挂载关系、节点间连通性与配置一致性检查,是集群变更前后的标准动作。
redis-cli --cluster add-node 扩容
add-node 把新节点加入集群:作为主节点加入后用 reshard 分配槽;作为从节点加入时用 --cluster-slave --cluster-master-id 指定归属。
集群的能力边界与限制
需明确的边界:不支持多库、多 key 操作需同槽、16K 槽数量固定、故障切换非强一致、大 key 与热点在单分片内无法分散。
cluster-node-timeout 的作用
节点间心跳超时判定:超过该时长未收到某节点消息,就标记为疑似下线(PFAIL),进一步多数确认后升级为 FAIL,触发从节点提升。
CLUSTER SLOTS:槽与地址映射
CLUSTER SLOTS 返回每个槽区间的主从地址(新版可能返回含额外字段的形式),客户端库据此建立路由表并按 MOVED 更新。
MIGRATE:跨节点迁移键
MIGRATE host port key dbid timeout 把键连同值迁移到目标实例,支持 COPY/REPLACE 选项;集群槽迁移的底层就是 MIGRATE 逐键搬运。
集群监控指标要点
监控清单:cluster_state、槽未覆盖数、节点 flags、主从复制偏移、单节点内存与延迟、MOVED/ASK 频率、总线消息统计。
redis-cli --cluster rebalance 均衡槽
rebalance 按各节点槽数与权重自动计算并迁移,使槽分布接近均衡;--cluster-use-empty-masters 让空主节点也参与分配。
redis-cli --cluster del-node 缩容
del-node 移除节点:删主节点前必须先把它负责的槽迁走(reshard 到其他节点),删从节点可直接执行。
集群备份策略
集群备份按节点执行:逐节点 BGSAVE 后拷贝快照(或逐节点复制数据目录),同时备份各节点的 nodes.conf 与配置文件,保证可还原拓扑与数据。
集群安全加固要点
集群同样需要认证与网络隔离:设置 requirepass 与 masterauth(或 ACL 用户),集群总线端口只在可信网络暴露,避免把 16xxx 端口暴露公网。
cluster-config-file(nodes.conf)
nodes.conf 保存集群拓扑、节点 ID、槽分配与纪元信息,由节点自动维护;集群每个节点有各自的一份,推荐按端口区分文件名。
CLUSTER MEET 组建集群
CLUSTER MEET ip port 让两个节点握手并交换拓扑:后续通过 gossip 逐步发现全网节点,是手工组建集群的第一步。
cluster-announce-ip/port:地址公告
NAT 或容器环境中,节点实际地址与对其他节点可见的地址不同:用 cluster-announce-ip/port/bus-port 公告可达地址,否则节点间互相连接失败。
CLUSTER SHARDS(7.0+)
7.0 新增 CLUSTER SHARDS:以「分片」为单位返回主从节点与槽范围,输出对自动化更友好,逐步替代手工解析 SLOTS。
CLUSTER ADDSLOTS:分配槽位
CLUSTER ADDSLOTS slot... 把未分配的槽指派给当前节点;只能指派无人认领的槽,接管他人槽要先用 SETSLOT 迁移流程。
CLUSTER REPLICAS 查看从节点
CLUSTER REPLICAS <node-id> 列出指定主节点的从节点与状态,用于确认主从配对是否完整、从节点是否健康。
READONLY:从节点读数据
集群从节点默认拒绝读请求(会重定向到主节点):客户端发送 READONLY 后可读取本从节点数据(可能略旧),适合读多写少场景分摊压力。
集群滚动升级流程
滚动升级按「从节点 → 主节点切换 → 原主节点」推进:先升从库,再把主库切到已升级从库(FAILOVER),最后升级旧主库并重新入群。
CLUSTER COUNTKEYSINSLOT 查槽内键数
CLUSTER COUNTKEYSINSLOT slot 返回指定槽当前保存的键数量,常用于迁移前评估数据量、确认缩容迁移完成。
CLUSTER FORGET 移除节点
CLUSTER FORGET node-id 从本地拓扑中移除指定节点,并在一分钟内拒绝该节点重新加入(防止 gossip 立刻把它带回来),需要一个一个节点执行。
CLUSTER REPLICATE:设置从节点
在节点上执行 CLUSTER REPLICATE <master-node-id> 把它变为指定主节点的从库;节点需要是空实例(无槽、无数据)。
ASKING:迁移中的临时通行证
收到 ASK 后客户端先向目标节点发送 ASKING,再重发原命令;ASKING 只对紧接的一条命令有效,用于槽迁移中间态的访问。
CLUSTER GETKEYSINSLOT 取样键名
CLUSTER GETKEYSINSLOT slot count 返回该槽内至多 count 个键名,用于抽样验证与迁移脚本分批处理。
CLUSTER RESET 重置节点
CLUSTER RESET [HARD|SOFT] 让节点放弃槽并退出集群身份:SOFT 保留节点 ID 与节点列表,HARD 一并清空并生成新 ID,实例回到「未入群」状态。
CLUSTER LINKS 查看节点连接
7.0+ 提供 CLUSTER LINKS:列出本节点与其他节点的集群总线连接(方向、创建时间、最后交互),用于排查总线层通信问题。
配置纪元(epoch)与冲突解决
每个节点维护 config epoch:槽归属冲突时纪元大者胜出;从节点在故障切换后递增纪元并广播,避免旧信息覆盖新拓扑。
cluster-require-full-coverage 取舍
该配置决定槽覆盖不全时集群是否对外可用:yes(默认)要求全部槽在线,no 则允许在部分槽失效时继续服务可用槽。
CLUSTER SET-CONFIG-EPOCH 手工组网
手工组建集群时先为各节点设置互不相同的 config epoch,再执行 CLUSTER MEET 与槽分配,避免自动收敛产生冲突。
cluster-migration-barrier 副本迁移门槛
cluster-migration-barrier 控制主节点至少保留多少可用副本后,才允许把多余副本迁往无副本的主(默认 1),影响自动副本迁移的活跃度。
CLUSTER COUNT-FAILURE-REPORTS 故障报告
CLUSTER COUNT-FAILURE-REPORTS node-id 返回有多少节点把目标节点标记为疑似失败,用于分析失败判定的传播与误判。
内存与管理
内存分析、淘汰策略与碎片整理
EXPIRE 家族与选项:NX/XX/GT/LT
EXPIRE/PEXPIRE/EXPIREAT/PEXPIREAT 覆盖秒与毫秒、相对与绝对四种组合;7.0 起支持 NX/XX/GT/LT 选项控制只在无 TTL、已有 TTL、更长、更短时生效。
过期机制:惰性删除加定期抽样
过期键不会被定时器精确唤醒删除:读取时惰性判定,同时后台周期性随机抽样清理;过期数据占内存的时间取决于抽样强度与写入压力。
键空间通知:监听键的变化事件
开启 notify-keyspace-events 后,Redis 把写入、过期、删除等事件发布到 __keyspace@0__ 与 __keyevent@0__ 频道,可驱动缓存失效等联动。
八种 maxmemory-policy 对照
淘汰策略分四族:noeviction、allkeys 三兄弟(lru/lfu/random)与 volatile 三兄弟(lru/lfu/random),另有 volatile-ttl 按剩余时间淘汰。
INFO memory 关键字段解读
INFO memory 输出字段按口径分组:used_memory 系列、rss 系列、碎片率、峰值与分配器统计,读懂口径才能正确告警。
Redis 内存构成总览:dataset 与 overhead
内存由数据集(用户键值)与非数据集开销(键空间结构、客户端缓冲、复制缓冲、Lua 脚本等)两部分组成,排查前先分清涨的是哪一块。
淘汰策略怎么选
纯缓存实例用 allkeys-lru 或 allkeys-lfu;带持久数据与缓存混部用 volatile 系并确保缓存键都有 TTL;不允许丢数据的实例用 noeviction 并配套告警。
used_memory 与 rss 为何不一致
used_memory 是 Redis 自己统计的分配量,rss 是操作系统实际映射的物理内存;分配器碎片、未归还页、THP 与 fork 拷贝都会让两者出现差距。
动态调整 maxmemory 的正确姿势
运行中调整 maxmemory 立即生效:调低可能即时触发淘汰或拒绝写入,调高不会回退已淘汰数据,操作前先评估业务影响。
LFU 双参数:log-factor 与 decay-time
lfu-log-factor 控制频率计数增长的对数曲线(越大越难涨),lfu-decay-time 控制衰减速度(单位分钟,访问间隔超过该值计数器减一档)。
lazyfree:把删除挪到后台线程
lazyfree 系列配置把大对象释放工作交给后台线程执行,避免主线程删除大键时长时间阻塞,是延迟敏感实例的常用开关。
编码阈值与内存:listpack 家族
hash、zset、list 等类型在小规模时用紧凑编码(Redis 7 为 listpack,此前为 ziplist),超过条目数或元素大小阈值转为标准结构。
内存监控指标采集清单
内存监控建议采集:used_memory、used_memory_rss、maxmemory、evicted_keys、expired_keys、mem_fragmentation_ratio、客户端缓冲与连接数、键数量。
内存碎片处理路径
碎片偏高时按路径决策:先确认系统内存余量,再评估启用 activedefrag 在线整理或安排重启窗口,重启前先保存持久化文件。
noeviction 下的 OOM 报错
noeviction 达到 maxmemory 后,写命令返回 OOM command not allowed when used memory > maxmemory,读命令不受影响(可配命令级放行)。
LFU 淘汰:按访问频率说话
LFU(Less Frequently Used)按访问频率淘汰,频率随时间衰减;适合热点长期稳定的缓存,能缓解偶发访问把冷键顶成热点的问题。
evicted_keys:淘汰量观测
evicted_keys 统计被淘汰键的累计数量,是判断内存压力与淘汰强度的直观指标;短时间飙升说明容量已跟不上写入。
淘汰尽力值:maxmemory-eviction-tenacity
maxmemory-eviction-tenacity(默认 10)控制内存超限时 Redis 在淘汰上投入的力度,值越高越积极回收,代价是更多 CPU 与延迟。
一个键的内存都由什么组成
单个键的成本包括:键字符串对象、值对象、主字典的表项与散列结构、过期表条目(有 TTL 时),以及内存分配对齐损耗。
replica-ignore-maxmemory 与副本内存
默认副本忽略自己的 maxmemory 限制(受主库驱动),需要独立控制副本内存时设置 replica-ignore-maxmemory no,但要防范副本主动淘汰造成数据面不一致的困惑。
内存水位规划:给谁留余量
为 maxmemory 设水位时预留三类余量:fork/重写时的写时复制、碎片与分配器损耗、系统与其他进程占用;常见经验是给系统留出可观比例。
字段级 TTL 与内存新选择
Redis 7.4 起支持对 hash 字段设置独立过期(HEXPIRE/HPEXPIRE 等);字段级 TTL 比整键 TTL 更精细,代价是字段过期记录的内存与回收成本。
maxmemory:内存上限的设定
maxmemory 以字节为单位设置实例可用内存上限,支持 100mb、1gb 这类可读写法;留 0 表示不限制(64 位默认)。
近似 LRU:采样淘汰原理
Redis 不维护全量 LRU 链表,而是给对象记录最近使用时间戳,淘汰时采样若干键挑较久未用的;采样数越大越接近真实 LRU。
共享整数对象与内存节省
Redis 默认共享 0 到 9999 的整数对象,命中时多个键复用同一对象,能显著节省小整数场景内存。
过期表的内存代价
每个带 TTL 的键都有一份过期时间记录,过期表与主字典独立维护;大量 TTL 键会带来可观的内存与 CPU 扫描成本。
大 key 的内存拆分思路
大 key 治理分两步:先定位(MEMORY USAGE、--bigkeys、采样统计),再拆分(按业务维度水平切分或按字段垂直拆)。
zset 按时间或范围分片
排行榜等超大 zset 可按时间窗(日/周)或分数区间拆成多个 zset,历史分片设 TTL 过期或归档,控制单键增长。
maxmemory-clients:客户端内存总量治理
maxmemory-clients 限制所有客户端连接缓冲(查询缓冲、输出缓冲)可用的内存比例或绝对值,超限时按用量驱逐客户端。
swap 与 Redis:延迟的头号隐患
Redis 内存被换出到 swap 后访问延迟从微秒级恶化到毫秒级;生产环境通常建议关闭 swap 或把 vm.swappiness 调到很低。
何时该扩容:判断信号
扩容信号包括:淘汰速率上升且命中率下降、used_memory 长期贴近上限、延迟随内存压力波动、写入 OOM 报错出现频次增加。
内存告急时的处置顺序
内存告急按顺序处理:确认报错范围(写拒绝/淘汰加剧)→ 定位增长源(客户端缓冲/大键/写入暴增)→ 止血(限流、清理可再生成的键)→ 再谈扩容。
碎片整理参数:阈值与节奏
active-defrag-ignore-bytes 设定最小碎片量门槛,active-defrag-threshold-lower/upper 控制启停百分比,cycle-min/max 控制每轮 CPU 占比。
客户端缓存与 tracking 表内存
CLIENT TRACKING 让服务端记录客户端读过哪些键,变更时推送失效消息;tracking 表本身占内存,规模大时需要设上限。
序列化方案对内存的影响
同一数据结构用 JSON、MessagePack、Protobuf 存储的体积差异可观;压缩与二进制序列化能显著降低 value 内存,但增加 CPU 编解码成本。
内存排查一页清单
内存问题按清单推进:看 INFO memory 构成 → MEMORY DOCTOR 建议 → 排查客户端与复制缓冲 → 抽查大键与键增长 → 评估碎片与系统内存 → 决定治理或扩容。
广播模式追踪:BCAST 与 PREFIX
CLIENT TRACKING ON BCAST PREFIX 前缀 用前缀广播取代按键记录:服务端不再为每个键维护追踪记录,内存更省,代价是前缀内变更都会通知。
jemalloc 分配器与内存统计
官方包默认使用 jemalloc,按尺寸分级管理内存页;used_memory 基于分配器口径,因此与 malloc 家族行为相关。
MEMORY USAGE SAMPLES 采样精度
MEMORY USAGE key SAMPLES n 指定对集合内元素的采样数量;样本为 0 表示全量扫描,适合精确核对。
lazyfree-lazy-user-del 与 user-flush
lazyfree-lazy-user-del yes 让 DEL、lazyfree-lazy-user-flush yes 让 FLUSHDB/FLUSHALL 默认走异步释放,改动属主路径行为需谨慎。
超大 hash 的分桶拆分
把超大 hash 按取模分桶为多个小 hash(如 user:tag:1001:0..N),单键操作 O(1),也便于分批迁移与压缩编码受益。
list-compress-depth:列表压缩深度
quicklist 由多个节点组成,list-compress-depth 控制两端各多少个节点不压缩、中间节点压缩存储,平衡内存与访问成本。
normal 客户端输出缓冲上限
普通客户端的输出缓冲默认不设限或限制宽松,大量积压会直接吃掉实例内存;按业务响应速度设置合理上限能防患于未然。
repl-backlog-size 的内存占用
主库复制积压缓冲 repl-backlog-size 常驻占用内存(默认 1MB,生产常调大),用于从库短暂断连后的增量续传。
MEMORY 命令家族速览
MEMORY 家族覆盖测量(USAGE)、诊断(DOCTOR/STATS/OVERHEAD)、维护(PURGE)与分配器(MALLOC-STATS),按目的选用。
tracking-table-max-keys 上限控制
tracking-table-max-keys 限制跟踪表记录数(默认 1000000),达到上限后新键会挤掉旧记录,被挤出键的客户端可能收到失效通知但不再精确跟踪。
淘汰引发的延迟尖峰
内存超限时淘汰动作会插入命令执行路径,链式淘汰或多键操作可能放大单次延迟;观察淘汰速率与延迟曲线的时间相关性可确认。
命中率与内存的平衡
给缓存分配更多内存通常提升命中率,但收益递减;命中率下滑且内存未满时,问题多半在过期策略或访问模式而非容量。
内存指标的自动化采集要点
自动化采集建议做成脚本解析 INFO,标注实例名、角色(主/从)、版本;用时间序列存储并设置差值告警,避免单点数值误判。
重定向失效:REDIRECT 代收消息
CLIENT TRACKING ON REDIRECT 客户端ID 把失效消息转发给指定连接(该连接订阅失效频道),适合连接池共享一份缓存追踪。
删除键后内存不立刻下降的原因
内存不立即回落常见三因:分配器保留空闲页不归还系统、异步释放(UNLINK/lazyfree)滞后、碎片与缩容渐进;都属于机制内行为。
大 value 写入的多重代价
单个大 value(如数十 MB 字符串)写入会同时带来:主线程拷贝阻塞、复制缓冲峰值、网络传输尖峰与内存碎片;拆分或压缩是常用对策。
容器内存限制与 maxmemory 的关系
容器环境里 cgroup 限额先于 maxmemory 生效:RSS 触顶会直接触发 cgroup OOM 杀进程;maxmemory 应按限额留出余量设置并监控 RSS。
版本演进中的内存相关变化
Redis 7.0 起 hash 与 zset 的紧凑编码由 ziplist 改为 listpack,相关配置名从 *-max-ziplist-* 变为 *-max-listpack-*;升级前核对配置迁移。
mem_fragmentation_ratio 是什么意思
该比值为 used_memory_rss 除以 used_memory:大于 1 表示有碎片的可能,小于 1 通常意味着内存被换出或内存被压缩。
maxmemory-samples 调参与开销
提升 maxmemory-samples 可改善淘汰命中率,代价是每次淘汰的 CPU 采样成本;低延迟实例适度提高,吞吐受限实例保持默认。
lazyfree-lazy-eviction:淘汰也异步
lazyfree-lazy-eviction yes 让淘汰动作异步释放内存,降低淘汰瞬间的阻塞,但释放会略滞后于淘汰决策。
UNLINK:非阻塞删除大键
UNLINK 与 DEL 语义相同但把内存释放工作交给后台线程,删除超大集合时用它替代 DEL 可明显降低阻塞。
FLUSHALL ASYNC 与 FLUSHDB ASYNC
FLUSH 命令支持 ASYNC 选项在后台线程清空键空间,避免清库瞬间的主线程长阻塞;默认 SYNC 行为是同步释放。
客户端驱逐与观察
启用客户端内存限制后,超限客户端会被断开(evicted_clients 计数);客户端侧表现为连接中断,服务端日志记录原因。
pubsub 输出缓冲与慢订阅者
发布订阅客户端的输出缓冲由 client-output-buffer-limit pubsub 控制,慢消费者会让缓冲堆积并最终被断开。
查询缓冲:大命令的内存账
客户端发送大命令(如巨量参数的 MSET)时,服务端需要缓存请求内容,查询缓冲计入客户端内存;单条超大命令还可能触发协议缓冲峰值。
渐进式 rehash 与双表过渡
字典扩容时保留新旧两张哈希表渐进迁移,期间内存短时接近翻倍、访问走两表;大字典扩容是内存尖峰的常见来源。
activedefrag:在线碎片整理
activedefrag yes 让 Redis 在空闲周期自动搬迁内存页降低碎片;开启条件与力度由 thresholds 与 cycle 系列参数控制。
客户端压缩:什么时候值得做
value 较大(如几十 KB 以上)且访问频次中等时,客户端压缩收益明显;高频读写的小 value 压缩往往得不偿失。
多库使用的内存与运维代价
多数据库(SELECT 0..15)共享同一套内存与配置,跨库操作受限、集群模式仅支持 0 号库,工程上通常单库 + 前缀分区。
过期回收与内存释放节奏
过期键内存释放由被动访问触发与主动抽样两种路径完成;抽样比例(如 hz 与 ACTIVE_EXPIRE 相关配置)决定回收及时性。
内存告警阈值设计
常用警戒线:用量持续超过上限的一定比例、淘汰速率持续为正、碎片率越过经验值、RSS 接近容器限额;阈值要按角色区分主从。
容量估算:从单键均重出发
估算方法:抽样测量单键平均内存(按类型分层)乘以预估键数,再叠加固定开销与峰值余量;上线后持续校准替换估算。
键名长度也是内存成本
每个键都完整保存键名,长前缀与冗长命名在大键量下占用可观内存;用缩写前缀并统一规范,测量后再优化。
字典缩容:装载率过低时回收
键被大量删除后,主字典装载率低于约 10% 时会触发缩容,把哈希表迁移到更小规格释放内存,属于渐进过程。
抽样统计键内存分布
用 SCAN 抽样一批键逐个 MEMORY USAGE,得到内存分布直方图;比单看 top 大键更能发现大量中键累积的贡献。
小对象聚合:用 hash 摊薄开销
大量结构相同的小对象可聚合进一个 hash:共享一个键与过期记录,dictEntry 与对象头开销被摊薄,适合画像、设置项类数据。
内存例行巡检清单
例行巡检项:用量水位与趋势、碎片率、淘汰与过期速率、客户端与复制缓冲、大键扫描结果、键数增长;异常项进入治理队列。
本地缓存与 Redis 的分层账
多层缓存(本地 + Redis)降低延迟与流量,但引入一致性维护成本;本地缓存要设短 TTL 或依赖失效通道,内存预算按层分配。
集群实例的内存汇总方法
集群内存分散在各节点:逐节点采集 INFO memory 汇总总量与水位,同时看槽分布与热点,避免均值掩盖个别节点紧张。
OBJECT FREQ 读取频率计数
OBJECT FREQ 返回键的 LFU 访问计数(对数刻度)与空闲时间的内部编码;需 LFU 策略下才有意义。
OBJECT IDLETIME 与空闲分析
OBJECT IDLETIME 返回键的空闲秒数(自上次访问);LRU 系策略下可用来抽查哪些键长期无人访问。
MEMORY USAGE:单键内存测量
MEMORY USAGE key 返回键及其值的估算字节数,包含键对象与值对象开销,是拆解大 key 与验证优化效果的直接工具。
MEMORY STATS 结构化内存视图
MEMORY STATS 以键值形式返回内存分布:峰值、dataset、overhead、客户端缓冲、复制缓冲、分配器统计等,便于脚本采集。
used_memory_dataset_perc:数据占比
used_memory_dataset_perc 表示数据集内存占总内存的百分比,可快速判断内存主要花在数据本身还是各类开销上。
装载因子与扩容时机
字典在装载因子超过阈值(约 1,且允许后台保存时放宽到 5)时触发扩容,扩容倍数按需翻倍,理解后可预判内存台阶。
连接数也是内存成本
每个客户端连接都有固定开销(socket 缓冲、查询/输出缓冲结构等),数千连接会带来可观的常驻内存。
Lua 脚本与函数的内存
Lua 脚本与 Redis Functions 占用独立内存统计(used_memory_lua / used_memory_functions),脚本缓存过多会体现在这两项。
used_memory_peak 与峰值复盘
used_memory_peak 记录历史内存峰值,事后复盘的内存台阶、扩容时间点与业务事件可以在这条线索上对齐。
内部碎片:分配尺寸的舍入损耗
分配器按尺寸分级分配,小对象请求会被舍入到更大的档位,形成内部碎片;大量小对象实例的损耗在总量上并不可忽略。
NUMA 服务器的内存访问差异
多路服务器上跨 NUMA 节点访问内存延迟更高;单进程大内存的 Redis 对内存分布敏感,排查时留意跨节点访问与系统 numa balancing 状态。
内存与延迟的联合分析
内存压力与延迟尖峰常同现:淘汰、过期风暴、碎片整理、大键删除都会同时打入两边指标;联看时间轴能快速锁定关联事件。
突发写入的内存峰值管理
突发批量写入会同时抬高数据集与客户端缓冲:控制批次大小与写入速率,把峰值摊平;压测验证峰值余量后再上线。
内存增长预测与扩容排期
用周环比与季节因子外推增长,结合扩容交付周期倒排时间点;增长突然变陡先排查异常来源再排扩容。
MEMORY PURGE:请求分配器归还
MEMORY PURGE 要求分配器将未使用的内存页归还操作系统,是缓解 rss 高企的即时手段之一,但可能带来短暂阻塞。
lazyfree-lazy-expire:过期异步回收
lazyfree-lazy-expire yes 让过期键的释放走后台线程,适合过期量大且对象较大的缓存场景。
lazyfree-lazy-server-del:内部删除异步
lazyfree-lazy-server-del yes 使服务端内部触发的删除(如字典扩容、类型转换、集合运算中间结果)异步释放内存。
键空间指标与内存互证
INFO keyspace 给出各库键数与带 TTL 键比例,与 used_memory 交叉验证可判断增长来自键数还是单键体积。
对象时间戳与 LRU 时钟精度
对象的最近访问时间戳以秒级时钟记录(24 位),长时间不访问的键时钟会回绕;理解精度对解读淘汰行为有帮助。
OBJECT REFCOUNT 读引用计数
OBJECT REFCOUNT 返回对象引用计数;共享对象(如整数)显示为固定的大数值(2147483647),普通键则为 1 附近。
MEMORY DOCTOR:一键内存体检
MEMORY DOCTOR 汇总内存状态并给出人话建议:碎片是否偏高、是否接近上限、是否有大量换出等,适合作为排查起点。
MEMORY MALLOC-STATS 分配器细节
MEMORY MALLOC-STATS 输出分配器(通常 jemalloc)的分级统计,用于确认内部分配区与碎片结构,属于深度排查工具。
MEMORY OVERHEAD 分配开销分析
MEMORY OVERHEAD 展示不同数据结构的分配开销分布与总量,帮助判断内存是被数据占用还是被结构开销吃掉。
性能与排障
慢查询、阻塞与大 key 排查
SCAN 游标遍历替代 KEYS
SCAN 用游标分批迭代键空间,每次返回一批与下一个游标,直到游标为 0;它不长时间阻塞服务,是生产环境枚举键的标准方式。
HSCAN/SSCAN/ZSCAN 遍历容器元素
对 Hash/Set/ZSet 使用对应 SCAN 家族命令渐进遍历大容器,避免 HGETALL/SMEMBERS 一次性返回海量元素造成阻塞。
TTL 批量检查与过期状态判定
TTL 返回 -1(存在但无过期)与 -2(键不存在)两种特殊值;批量检查用 SCAN 迭代配合管道,避免在生产实例上用 KEYS 全量扫描。
O(N) 命令雷区清单
复杂度随数据量线性或更差的命令要主动规避:KEYS、HGETALL、SMEMBERS、LRANGE 大范围、SORT、ZRANGEBYLEX 全量等,量大时都可能阻塞主线程。
常见错误信息速查表
排障常遇错误速查:LOADING(加载中)、READONLY(副本禁止写)、MISCONF(持久化失败被禁写)、OOM(内存超限)、CLUSTERDOWN(集群不可用)、NOSCRIPT(脚本丢失)、BUSY(脚本超时占用)。
读懂慢日志条目字段
条目字段包括 id、timestamp、duration、args 与客户端信息(client_addr/client_name);先看 duration 量级再看 args 里的命令形状。
INFO stats 关键字段速查
INFO stats 覆盖吞吐、连接、命中与回收:instantaneous_ops_per_sec、total_connections_received、rejected_connections、keyspace_hits/misses 等。
延迟尖刺排查清单
排查顺序:确认影响面(命令/连接/时间段)→ 查 LATENCY 事件类别 → 查 SLOWLOG → 查持久化与内存侧信号 → 查系统与网络 → 定位并验证修复。
io-threads:多线程网络 IO
Redis 6 起可将网络读写分发到多个 IO 线程(io-threads),主线程仍负责命令执行;高网络负载实例可显著提升吞吐。
性能监控指标采集清单
性能侧建议采集:ops、命令延迟百分位、CPU(主/子进程)、网络吞吐、连接与阻塞数、慢命令计数、持久化与 fork 指标。
INFO 段落速览与取值清单
INFO 常用段落:server(版本/运行时长)、clients、memory、persistence、stats、replication、cpu、commandstats、latencystats、keyspace、cluster;排障按需取段。
慢查询定位流程
定位流程:SLOWLOG 找候选命令 → 复现并测复杂度 → 检查数据规模(大键/大集合)→ 评估是否集中触发(后台任务/批处理)→ 优化命令或数据结构。
延迟事件类别速查
常见事件类别:command(普通命令慢)、fork(持久化 fork 耗时)、expire-cycle(过期清理超时)、eviction-cycle(淘汰超时)等,按类别找根因。
redis-benchmark 参数详解
常用参数:-n 总请求数、-c 并发连接、-P 管道深度、-t 命令过滤、-r 随机键空间、-q 精简输出,组合出贴近业务的负载形状。
MISCONF 错误:持久化失败被禁写
当 RDB 保存失败(磁盘满、权限、fork 失败)时,stop-writes-on-bgsave-error 会让实例拒绝写入并报 MISCONF;先修持久化再恢复写入。
日志关键词与处置方向
常见告警关键词对应方向:overcommit 提示去查内核参数;THP 提示去关透明大页;Background saving error 查磁盘与 fork;MASTER <-> REPLICA sync error 查复制链路。
SLOWLOG GET:读取慢查询日志
SLOWLOG GET 返回超过阈值的命令记录,每条含执行耗时与参数;定位慢命令的常用入口,注意日志只存命令不含 keyspace 副作用。
slowlog-log-slower-than 阈值设定
slowlog-log-slower-than 以微秒为单位设定记录阈值(默认 10000);设为 0 记录所有命令、负值关闭记录。
latency-monitor-threshold 开启延迟监控
latency-monitor-threshold 设置延迟监控阈值(毫秒,0 关闭);开启后 Redis 按事件类别记录延迟尖峰,供 LATENCY 命令族查询。
redis-cli --bigkeys 键规模扫描
redis-cli --bigkeys 用 SCAN 遍历键空间并按类型找出各类型规模领先的键,输出元素数量或长度,是键治理的例行扫描。
CLIENT LIST 连接全景
CLIENT LIST 列出每个连接的信息:地址、空闲时间、缓冲用量、订阅数、最近命令等,排障时用来找出异常客户端。
INFO commandstats 命令调用画像
INFO commandstats 按命令统计调用次数、总耗时与平均耗时,用来找出调用量大或平均值偏高的命令。
大 key 检测:常用三招
检测大 key 的常用方法:redis-cli --bigkeys/--memkeys 抽样扫描、业务埋点记录键规模、MEMORY USAGE 定点核查怀疑对象。
tcp-backlog 与连接积压
tcp-backlog 定义已完成三次握手等待 accept 的连接队列长度(默认 511);高并发短连接场景需要同步放大内核 backlog 才能生效。
redis-benchmark 快速压测
redis-benchmark 内置压测工具,按命令类型生成负载并输出吞吐与延迟统计;用专属实例或测试环境运行,别对着生产库裸测。
memtier_benchmark 复杂负载模拟
memtier_benchmark 支持读写比例、键分布、数据集大小与集群模式,能构造更接近业务的混合负载,适合容量测试。
MULTI/EXEC 事务与执行语义
MULTI 开启事务、命令入队,EXEC 一次性顺序执行;入队期错误(如语法)导致 EXECABORT,执行期错误不会回滚已执行命令。
WATCH 乐观锁实践
WATCH 监视键,EXEC 前若被改动则事务放弃(EXEC 返回空);循环重试是标准用法,适合低冲突的读改写场景。
阻塞命令与等待语义
BLPOP、BRPOP、BLMOVE、BZPOPMIN 等阻塞命令在无元素时挂起连接等待,超时参数 0 表示一直等;滥用会堆积 blocked_clients。
单线程模型与瓶颈判读
命令在主线程串行执行,单条慢命令会阻塞后续全部请求;吞吐瓶颈通常不在 CPU 数量,而在命令结构与数据规模。
CPU 高的排查路径
排查路径:INFO cpu 看主/子进程 → commandstats 找高耗时命令 → SLOWLOG 抽样 → 排查大键与批量任务 → 系统层看是否有 fork/子进程重写并发。
连接风暴的处理
连接风暴表现:连接数陡增、rejected_connections 上升、内存与 CPU 双升;处理:限流入口、排查重连逻辑、检查 LB 与连接池配置。
BUSY:脚本超时占用
脚本运行超过 busy-reply-threshold(lua-time-limit)后,其他连接收到 BUSY;可用 SCRIPT KILL 终止只读脚本,有写操作的脚本需评估后走重启流程。
容量压测实施方法
压测方法:明确目标(容量/稳定性/瓶颈)→ 构造接近业务的负载模型 → 阶梯加压观察拐点 → 记录 Redis 与系统双视角数据 → 输出容量结论与风险点。
从日志定位问题的顺序
Redis 日志(logfile 配置路径)按时间线记录启动、持久化、复制与警告;排查时先看告警行(# 标记),再回溯上下文,与指标时间轴对齐。
内核 backlog:somaxconn 与 syn 队列
连接排队受内核参数约束:net.core.somaxconn 与 net.ipv4.tcp_max_syn_backlog 太小会在高并发建连时丢连接;与 Redis 的 tcp-backlog 配套调整。
延迟来源分层总图
延迟分层:网络往返、客户端排队、服务端排队(单线程等待)、命令执行、后台任务干扰、系统资源(CPU/内存/磁盘);每层都有对应证据工具。
延迟跟踪配置:latency-tracking
latency-tracking(默认 yes)开启命令延迟跟踪,latency-tracking-info-percentiles 定义 latencystats 使用的百分位列表(如 50 99 99.9)。
集群延迟来源与治理
集群额外延迟来源:客户端重定向(MOVED/ASK)、槽迁移期间的请求转发、跨节点访问;治理靠哈希标签共槽、客户端缓存与迁移窗口管理。
LATENCY LATEST:最新延迟事件
LATENCY LATEST 列出各事件类别的最新一次延迟尖峰与历史峰值(时间戳、耗时毫秒),快速判断延迟来源类别。
CLIENT KILL 断开问题连接
CLIENT KILL 按地址、ID、类型或过滤条件断开连接,处理异常客户端、慢消费者与连接泄漏的常用手段。
CLIENT PAUSE 暂停客户端命令
CLIENT PAUSE milliseconds [WRITE|ALL] 在指定时长内暂停处理客户端命令,常用于切换窗口让复制追平或脚本化变更。
MONITOR 的使用与风险
MONITOR 实时回显服务端处理的每条命令,适合短时抓取现场;开启的连接会拖慢实例吞吐,且能看到其他客户端的命令内容。
INFO latencystats 命令延迟百分位
INFO latencystats 提供命令级延迟百分位(p50/p99/p999),比平均耗时更能反映尾部体验;依赖延迟跟踪开启。
KEYS 的替代路径
KEYS 一次性扫描全键空间,生产环境应改用 SCAN 迭代或维护索引集合来按前缀取键。
HGETALL 大 hash 的读法
大 hash 上用 HGETALL 会一次性返回全部字段并占用输出缓冲;改造方向:HSCAN 分页、按业务拆分小 hash、只取需要字段的 HMGET。
大 key 的安全删除
删除大集合用 UNLINK 或分批删除(HSCAN+SHDEL 等),避免 DEL 同步释放造成长时间阻塞;删除前确认数据可弃。
管道压测与业务口径
管道(-P)通过减少往返放大吞吐,适合测量服务端处理上限;业务 QPS 容量评估应使用接近真实调用模式的压测。
管道(pipeline)批量提交原理
管道把多条命令一次性发出、批量读回,减少网络往返次数;命令本身仍是逐条执行,收益在网络层而非执行层。
CLUSTERDOWN:集群不可用
CLUSTERDOWN 表示集群状态不可用:常见于多数派主节点失联、槽位未完整覆盖、集群模式误配;先看 CLUSTER INFO 的 cluster_state。
性能告警阈值设计
性能告警建议双轨:硬阈值(延迟超过业务容忍、连接拒绝)与趋势阈值(延迟百分位持续抬升、慢命令增速),后者用于提前介入。
变更发布检查清单
Redis 变更上线前核对:变更内容与回滚方案 → 影响实例与角色 → 低峰窗口 → 备份与持久化状态 → 观察指标定义 → 执行与验证。
故障处理流程与分级
故障处理流程:确认影响面与级别 → 快速止血(切换/限流/断流)→ 定位根因 → 修复并验证 → 复盘改进;全程记录时间线与操作。
COMMAND 系列:命令元信息查询
COMMAND INFO 查询命令的元信息(参数、flags、复杂度),COMMAND DOCS 返回文档说明,客户端与排障脚本可据此裁剪命令集与复杂度。
INFO errorstats:错误分类计数
INFO errorstats 按错误前缀统计返回次数(如 ERR、WRONGTYPE、READONLY),能看出客户端到底在踩哪类坑,比单条报错日志更有全局视角。
压测的协调遗漏与真实延迟
按固定间隔发压的工具在系统变慢时会自动降低实际并发,测出的延迟低于真实用户感受(协调遗漏);改用闭环速率控制或纠偏工具。
服务节点系统指标清单
节点侧要采集:CPU(含 steal)、负载、内存与 swap、磁盘吞吐与 await、网络重传与丢包、句柄与连接数;与 Redis 指标按时间轴对齐。
客户端库选择与常见坑
选型关注:集群感知、超时与重试配置、连接池实现、RESP3 支持与维护活跃度;上线前检查默认值(不少库默认无超时)。
重试与退避:故障期的自保
重试策略按错误分类:可重试(LOADING/TRYAGAIN/网络抖动)才重试,指数退避加抖动;配合熔断避免重试风暴打垮恢复中的实例。
故障演练:切换与宕机剧本
演练剧本:主从切换、副本宕机、网络分区、节点重启;在生产镜像环境执行并记录 RTO 与数据行为,验证监控与告警覆盖。
集合运算与位图操作的规模风险
SINTERSTORE/SUNIONSTORE、BITOP、BITCOUNT 等随参与数据规模增长;大集合运算先评估规模,能限界就限界(如 SINTERCARD)。
健康检查设计要点
健康检查:PING 判活、关键指标判健康(内存水位/持久化状态/主从链路)、拓扑判角色;区分 liveness 与 readiness,超时短且避免重命令。
上线前性能预检清单
预检项:内存水位与余量、慢命令基线、大键扫描、连接上限与内核参数、持久化状态、监控告警就绪、压测报告归档。
集群模式压测要点
测集群要用支持集群路由的压测工具(如 memtier --cluster-mode):键分布要覆盖多槽,注意 MOVED 重定向开销与逐节点分配均匀度。
redis-cli --intrinsic-latency 系统基线
redis-cli --intrinsic-latency seconds 测量机器调度与内核本身的固有延迟(不涉及网络),作为延迟分析的系统基线。
redis-cli --memkeys 内存视角扫描
redis-cli --memkeys 与 --bigkeys 类似但按 MEMORY USAGE 口径统计内存,直接指出内存占比高的键。
redis-cli --hotkeys 热点键分析
redis-cli --hotkeys 基于 LFU 计数扫描热点键;requirement:maxmemory-policy 必须为 LFU 系,否则直接报错。
redis-cli --pipe 高速批量导入
redis-cli --pipe 把标准输入里的 RESP 协议数据批量灌入实例,用于大规模数据导入与迁移场景。
INFO cpu 与子进程 CPU
INFO cpu 给出主进程与子进程的系统/用户态 CPU 累计值;子进程 CPU 高通常对应持久化重写与 fork 工作。
LRANGE 大范围读取的替代
LRANGE 指定大区间会返回海量元素;分页读取(按区间切片)或改用 stream 消费模式更适合大列表场景。
SMEMBERS 大集合的替代
SMEMBERS 返回集合全部成员,大集合应改用 SSCAN 渐进遍历,或维护分片集合按需读取。
SORT 的复杂度与用法约束
SORT 默认 O(N log N),带 BY/GET 外部键引用时开销进一步放大;大集合排序建议迁移到 zset 或离线计算。
maxclients 连接上限
maxclients 限制同时连接的客户端数(默认 10000);达到上限后新连接被拒,rejected_connections 计数上升。
timeout 回收空闲连接
timeout 配置客户端空闲超过秒数后断开(默认 0 不回收);滥用会导致连接池频繁重建,通常交给客户端连接池管理。
unixsocket:本机调用的低延迟通道
同机客户端可经 Unix 域套接字连接(unixsocket 配置路径),免去 TCP 栈开销,延迟更低;权限通过 unixsocketperm 控制。
网络层排查:ping、mtr 与抓包
客户端侧排查顺序:ping 基础连通 → mtr 查路径抖动与丢包 → 对比不同源机器的延迟 → 必要时在两端抓包看握手与重传。
系统工具速查:top/iostat/vmstat
系统侧常用:top/htop 看 CPU 与进程、vmstat 看上下文切换与 swap、iostat 看磁盘与 fsync 压力,用于把 Redis 指标与系统事件对上。
perf 定位进程内热点
怀疑 CPU 花费在 Redis 内部时,用 perf top 观察函数级热点(如数据结构遍历、比较操作),将证据落到具体代码路径。
READONLY 错误:写错了实例
READONLY 表示向副本发起了写命令:检查路由配置与故障切换后的主从指认,切换窗口内客户端配置未更新是常见原因。
NOSCRIPT:脚本缓存未命中
EVALSHA 的脚本哈希不在缓存(实例重启或 SCRIPT FLUSH 后)时报 NOSCRIPT;标准处理是用 EVAL 回退重新加载一次。
MASTERDOWN 与 TRYAGAIN:重试类错误
复制链路异常时写入可能收到 MASTERDOWN(主库链接断开),集群操作在迁移或临时状态下可能返回 TRYAGAIN;这两类错误按可重试处理并带退避。
连接使用 IP 直连,规避解析风险
域名解析抖动或超时会直接表现为连接超时与重试风暴;客户端连接串尽量用 IP,域名切换通过配置或代理层控制。
指标采集频率的取舍
采集频率要平衡观测精度与开销:秒级适合压测与故障窗口,常态 10-60 秒足够;计数器用差分注意重启清零与回绕。
压测预热与冷启动偏差
压测结果受预热影响:JIT/内存分配器/页缓存与连接建立都需预热;固定数据集先跑一轮预热,取稳定阶段的读数。
连接复用:省下的是握手成本
短连接每次都要 TCP 握手、认证与初始化,高并发下连接建立本身成为延迟与 CPU 来源;连接池复用是客户端侧的基本优化。
LB 空闲超时与连接存活协同
负载均衡器的空闲超时若短于连接池保活间隔,池中连接会被静默断开;双方参数对齐并留出心跳余量。
热点分布建模:Zipf 而非全随机
真实访问多呈幂律分布;压测键分布用 Zipf 类模型比全随机更接近真实,避免低估热点键的放大效应。
重启后的冷启动与流量涌入
重启后的实例:页缓存与内存初态都冷,若全量流量瞬间恢复,加载与请求并发争抢;恢复策略要阶梯放量并观察。
跨机房访问与就近部署
跨机房访问把 RTT 直接加到每条命令上;读多写少可考虑就近读副本,写路径尽量收敛到同一区域,同步跨区链路质量要监控。
TLS 加密的连接与吞吐成本
TLS 增加握手与加解密开销:短连接场景握手成本显著,长连接与连接复用下成本收敛;上线前压测对比并确认 CPU 余量。
慢日志定期归档与分析
把 SLOWLOG GET 定期拉到日志系统(归档后可按命令聚合),并基于条数做告警;比人工翻看快照可靠。
MGET/MSET 合并往返
把多次单键读写合并成 MGET/MSET:往返次数下降、总延迟更小;注意单条命令的参数规模与单次延迟上限。
超时设计:连接、读写与命令
超时分层设置:连接超时最短、读超时按 p99 留余量、总超时封顶;避免无限等待,也要避免过短误杀正常慢查询。
背压:下游慢时的自我保护
当 Redis 变慢,上游若无背压会不断堆积:用有界队列、入口限流、熔断降级(本地缓存兜底)把压力挡在业务之外。
运维手册(Runbook)要素
Runbook 至少包含:拓扑与角色图、常见故障处置步骤、命令速查、升级与回滚路径、联系人升级链;定期随架构更新。
复盘方法与行动项跟踪
复盘输出:时间线、根因、影响面、改进项(含负责人与期限);改进项进入任务系统跟踪,未完项在下次复盘回顾。
内核网络缓冲区与大数据流量
大响应或大吞吐场景,内核 rmem/wmem 上限可能成为约束;按实测证据调整 net.core.rmem_max 等参数,别默认全调大。
TCP_NODELAY 与 Nagle 延迟
客户端小包连续写可能触发 Nagle 与延迟确认交互,追加约 40ms 量级延迟;多数客户端库默认开启 TCP_NODELAY,自研客户端应显式设置。
尾延迟治理手段清单
尾延迟治理:减少往返(批量/管道)、拆分慢命令、限制单命令规模、就近部署、容量留余量、隔离批任务与在线流量。
缓存预热:重建命中率
清空或切换后缓存全冷:预热方案要提前准备(热点键清单、来源回放、渐进放量),并监控命中率恢复曲线。
读懂压测的延迟分布表
redis-benchmark 输出含百分比分布与累计分布:重点看 99%、99.9% 档位,对照目标 SLA 判断是否达标,而非只看平均值。
应用启动的连接预热
应用发布时批量建连会形成瞬时压力:连接池分阶段填充、预热完成再放流量,避免启动即高峰。
slowlog-max-len 缓冲区长度
slowlog-max-len 控制慢日志保留条数(默认 128),超出后旧条目被丢弃;排查窗口短的场景适当调大。
LATENCY HISTORY 追踪单个事件
LATENCY HISTORY event 返回指定事件类别的历史尖峰序列,用于观察延迟问题的时间分布与是否周期性。
LATENCY DOCTOR:延迟体检报告
LATENCY DOCTOR 汇总延迟事件并给出解读与操作建议,是把原始数据翻译成结论的快捷工具。
redis-cli --latency 往返延迟测量
redis-cli --latency 持续发送 PING 并统计往返延迟(均值与极值),用于快速判断服务端响应是否稳定。
CLIENT NO-EVICT 保护关键连接
CLIENT NO-EVICT on 把当前连接标记为不可被客户端内存驱逐,监控与运维连接可用它保命。
CLIENT NO-TOUCH 读取不扰动热度
CLIENT NO-TOUCH on 让当前连接的读取操作不更新 LRU/LFU 热度,防止巡检类访问污染热点统计。
INFO clients 连接指标
INFO clients 提供 connected_clients、blocked_clients、tracking_clients 与客户端缓冲总量,连接异常的入口指标。
tcp-keepalive 与死连接清理
tcp-keepalive(默认 300 秒)让内核定期探测连接存活,及时发现半开连接;跨公网与负载均衡场景价值更高。
RESP3 与 HELLO 握手
HELLO 3 把连接协议切换为 RESP3,支持字典、集合等原生类型映射;扩容新客户端前确认服务端与 SDK 的协议支持。
后台线程(bio)都做什么
后台线程负责关闭大文件、AOF fsync、异步释放内存等任务;bio 任务积压会表现为内存回收慢或 fsync 延后。
LOADING 错误:加载窗口的重试
实例启动加载 RDB/AOF 期间返回 LOADING 错误,多数客户端库会按配置重试;集群切换或全量同步后的窗口也可能出现。
hz:定时任务频率
hz 控制后台任务(过期清理、超时检测等)的执行频率,默认 10 即每秒 10 次;调高更及时但增加 CPU 占用。
性能基线:建立与对比
性能基线要固定条件:同版本、同数据规模、同采集窗口、同负载模型;基线用于回答「这次变更前后差多少」。
性能回归检测方法
回归检测:关键路径压测脚本回归(固定数据集)+ 线上黄金指标监控 + 发布关联分析;三者结合区分「发布引起」与「自然漂移」。
延迟百分位:p99 才是体验
平均值掩盖长尾:看 p50 判常态、p99 判大多数人最差体验、p999 判极端尾部;按业务容忍度选目标百分位。
max 延迟指标的误导性
单点 max(最长一次延迟)受极端个例影响大,不适合作为主要告警;更有用是「超过阈值的次数」和百分位组合。
CPU steal 与虚拟化延迟
steal 表示 CPU 被宿主机其他虚拟机抢占的时间;steal 高时 Redis 延迟尖峰与自身负载无关,需要平台侧排查。
时钟同步与时间戳对齐
慢日志、延迟事件与业务日志的时间线要对齐,前提是各机时钟同步(NTP/chrony);时钟漂移会让关联分析失效。
MTU 与分片重传问题
跨专线、隧道(VPN/overlay)环境 MTU 变小,未适配时大包分片导致重传与吞吐下降;用 ping 带 DF 位探测路径 MTU。
redis-cli --latency-history 长观测
redis-cli --latency-history 按时间窗滚动输出延迟的 min/avg/max 序列(默认窗口约 15 秒),适合长时间观察波动。
redis-cli --lru-test 缓存负载模拟
redis-cli --lru-test <keys> 模拟带倾斜访问分布的缓存负载,用于观察真实缓存模式下的命中与内存表现。
SLOWLOG 维护命令:LEN 与 RESET
SLOWLOG LEN 查看当前条数,SLOWLOG RESET 清空日志;变更窗口前后用 RESET 得到干净样本。
LATENCY RESET 清理采样
LATENCY RESET 清空延迟事件统计,可指定事件名;变更或修复后重置基线,便于验证改善效果。
redis-cli --stat 实时状态面板
redis-cli --stat 周期性刷新关键指标(键数、内存、连接、命令速率等),适合快速巡检与观察压测时的水位变化。
CLIENT INFO 单连接详情
CLIENT INFO 返回当前连接的详细信息,客户端在报错时带上它,服务端排查时能看到该连接的完整状态。
dynamic-hz:自适应频率
dynamic-hz(默认 yes)让 Redis 在客户端多时提高后台任务频率、空闲时降低,平衡响应与开销。
CLIENT UNPAUSE 解除暂停
CLIENT UNPAUSE 立即恢复被 CLIENT PAUSE 挂起的命令处理,用于提前结束暂停窗口。