大 value 写入的代价
写入单个大 value(例如几十 MB 的字符串)代价是多重的:主线程要先接收并拷贝这么大的数据,复制连接需要缓冲同等体量的内容,网络出现传输尖峰,内存分配还可能加剧碎片。受影响的不是那一条命令,而是同一时刻所有排队请求的延迟。
基本信息
| 阈值 | 按业务可容忍的延迟与内存水位评估,没有通用数字 |
|---|---|
| 主要代价 | 主线程阻塞、复制缓冲、网络尖峰、内存碎片 |
| 常用对策 | 拆分键、压缩存储、把大对象外置到对象存储 |
| 相关限制 | proto-max-bulk-len 与 client-query-buffer-limit 限制单命令体积 |
| 观测 | MEMORY USAGE、STRLEN、复制偏移差与延迟事件 |
典型使用场景
- 内容类业务:文档、图片等大对象不适合直接放在键里
- 复制环境:大 value 写入会同步放大从库与复制缓冲压力
- 迁移改造:把大对象移到对象存储,键里只留指针与元数据
- 压缩评估:先用真实样本测压缩比与 CPU 成本再决定
- 入口保护:在业务侧加体积校验,超限直接拒绝
- 压测回归:把大 value 写入纳入延迟回归用例
评估手段
评估手段
redis-cli MEMORY USAGE cache:doc:big # 单键内存占用
redis-cli STRLEN cache:doc:big # 字符串长度,确认实际体量
redis-cli CONFIG GET proto-max-bulk-len # 单个批量值的大小上限
redis-cli CONFIG GET client-query-buffer-limit # 客户端查询缓冲上限
redis-cli INFO replication | grep -E 'slave[0-9]+' # 写入期间观察从库偏移差
redis-cli LATENCY LATEST # 是否出现与写入时间对齐的延迟事件代价对照
| 环节 | 表现 | 影响 |
|---|---|---|
| 主线程 | 接收与拷贝大值占用执行时间 | 同刻其他请求排队 |
| 复制缓冲 | 从库积压时主库缓冲增长 | 内存上涨,可能触发客户端驱逐 |
| 网络 | 传输尖峰挤占带宽 | 其他请求延迟抖动 |
| 内存分配 | 大块分配加剧碎片 | 常驻内存上升且回落慢 |
| 持久化 | 重写与保存体积变大 | 磁盘占用与恢复时间增加 |
大对象更合适的归宿是对象存储,键里只留指针与元数据,这是内容类业务常见的演进路径。
拆分能缓解但不能消除风险:拆分后要同步改读写路径,否则业务仍然会把完整对象拼起来,问题只是换了位置。