水位该给谁留余量
给 maxmemory 设定水位,本质是回答「给谁留余量」。至少要留出三类空间:持久化 fork 时的写时复制峰值、碎片与分配器损耗、以及操作系统与其他进程的占用。把内存贴着上限跑,等于把故障留给业务高峰。
基本信息
| 预留一 | 持久化与写时复制的内存峰值 |
|---|---|
| 预留二 | 碎片与分配器损耗 |
| 预留三 | 系统与其他进程占用 |
| 容器场景 | maxmemory 必须明显低于容器内存限制 |
典型使用场景
- 新实例上线前确定 maxmemory 取值
- 容器化部署时核算限制与实例上限的关系
- 排查「已经设了 maxmemory 却被系统 OOM 杀掉」
- 容量评审时给出扩容触发条件
- 调整复制或持久化策略后复核余量是否仍足够
核算水位
核算水位
# 看实例自身水位与碎片比例
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'
# 看系统层面的可用内存与 swap 使用
free -m
# 容器环境核对内存限制(cgroup v2 与 v1 路径不同)
cat /sys/fs/cgroup/memory.max 2>/dev/null || cat /sys/fs/cgroup/memory/memory.limit_in_bytes
# 持久化期间的写时复制影响
redis-cli INFO persistence | grep -E 'rdb_bgsave_in_progress|aof_rewrite_in_progress'
redis-cli INFO stats | grep latest_fork_usec余量构成
| 余量项 | 为什么要留 | 参考做法 |
|---|---|---|
| fork 与写时复制 | 生成快照或重写期间的峰值占用 | 按写入量评估,留出一份可观比例 |
| 碎片与分配器 | 实际占用高于分配量 | 预留一到两成更稳 |
| 系统与其他进程 | 系统、监控、日志都要内存 | 不把内存全部交给实例 |
| cgroup 限制 | 限制低于实例上限会先被内核杀 | 限制明显高于实例上限加余量 |
| 主从角色差异 | 从库有额外缓冲与复制开销 | 从库比主库多留一档 |
留余量不是浪费:水位是安全边际,换来的是峰值期间仍能稳定服务。多数事故复盘里都能找到「配置贴着上限」这一条共同特征。
容器环境最常见的事故形态是内存限制小于 maxmemory 加余量:Redis 还没到自己的上限,进程已经被内核杀掉,触发的不是淘汰而是重启。