写时复制的开销怎么量
快照与重写都靠 fork 出子进程完成,子进程与父进程共享物理内存页,只有当某一方写入某个页时才复制这一页,这就是写时复制开销。监控方法是:在快照前后分别记录实例报告的常驻内存与进程实际占用的物理内存,对比差值就能看出这次快照真实吃掉了多少内存。写入越密集,被复制的页越多,开销越大。
基本信息
| 观测对象 | 实例报告的常驻内存与操作系统看到的进程内存 |
|---|---|
| 基线 | 快照开始前先记录一份,结束后再记录一份 |
| 放大因素 | 写入速率、键的分布、内存碎片程度 |
| 风险 | 内存余量不足时可能被系统杀掉进程 |
| 处置方向 | 安排在低峰、留足余量或提前扩容 |
典型使用场景
- 大实例做快照前评估需要预留多少内存余量
- 排查快照期间实例被系统杀掉的现象,确认是否为内存超限
- 为容器设置内存上限时把写时复制峰值计入规格
- 对比不同快照窗口下的开销差异,为编排策略提供依据
- 复盘历史故障时还原当时的内存变化过程
观测示例
观测示例
redis-cli INFO memory | grep -E 'used_memory:|used_memory_rss|mem_fragmentation_ratio'
ps -o pid,rss,vsz,cmd -p $(pgrep -d, redis-server) # 进程级内存视角
top -b -n 1 -p $(pgrep -d, redis-server) | tail -3 # 快速取值
redis-cli INFO persistence | grep rdb_bgsave_in_progress # 确认快照是否在进行
free -h # 机器层面剩余内存观测项判读
| 观测项 | 含义 | 异常表现 |
|---|---|---|
| 实例报告的常驻内存 | 分配器向系统申请并驻留的部分 | 快照后长时间不回落,说明页未归还 |
| 进程实际物理内存 | 操作系统口径的真实占用 | 明显高于报告值,说明存在额外复制页 |
| 碎片率 | 两者比值 | 偏高时写时复制开销更容易放大 |
| 机器剩余内存 | 系统层可用的余量 | 余量低于数据集规模时快照风险高 |
只看实例报告的总量会漏掉写时复制与碎片带来的真实占用,系统层要配合进程实际物理内存一起看。
内存吃紧时正确的做法是把快照安排在低写入时段或提前扩容,而不是先关掉写保护或压缩功能。