Redis不支持内存阈值自动触发bgsave,需外部监控:定时采集used_memory_rss或used_memory_percent,超阈值则执行redis-cli bgsave;须避坑碎片误判、超时卡死、并发冲突、单位未清洗、锁竞争及静态阈值滞后等问题。

Redis内存使用率超过阈值时自动触发bgsave
Redis本身不支持根据内存使用量自动调整RDB频率,bgsave必须由外部监控驱动。核心思路是:定时采集used_memory_rss或used_memory_percent,与预设阈值比较,超限则执行redis-cli bgsave。注意别用used_memory(含碎片),它可能远低于RSS,导致误判。
用redis-cli --stat解析实时内存指标
redis-cli --stat输出是滚动文本流,不适合直接解析;更可靠的是用INFO memory并提取关键字段:
redis-cli INFO memory | grep -E "used_memory_rss|used_memory_peak|mem_fragmentation_ratio"
常见陷阱:
- 未设置
timeout参数,脚本在Redis不可达时卡住——加-t 2限制连接超时 - 忽略
mem_fragmentation_ratio > 1.5场景:即使used_memory_percent不高,高碎片也可能触发OOM,建议一并监控 - 用
awk '/used_memory_rss/{print $2}'提取时没处理单位(如"1048576000b"),应先用sed 's/[^0-9]//g'清洗
Shell脚本中避免重复bgsave和并发冲突
连续多次调用bgsave会被Redis排队,但脚本若每秒检查一次,极易造成堆积。正确做法:
- 记录上一次
bgsave时间戳到临时文件(如/tmp/last_bgsave.ts),两次触发间隔至少设为60秒 - 执行前先查
redis-cli INFO persistence | grep rdb_bgsave_in_progress,值为1则跳过 - 用
set -o noclobber防止多实例同时写同一状态文件,或改用mktemp生成唯一锁文件
示例判断逻辑:
if [[ $(redis-cli INFO persistence | awk -F': ' '/rdb_bgsave_in_progress/{print $2}') == "1" ]]; then
echo "bgsave already running"
exit 0
fi
内存阈值设定要考虑业务写入节奏
静态阈值(如80%)在写入突增时可能来不及响应,动态阈值更稳妥:
- 取最近5分钟
used_memory_rss的移动平均,再乘以1.2作为当前阈值 - 对写密集型实例,把
maxmemory设为物理内存的70%,留30%给系统和fork开销 - 如果启用了
vm.overcommit_memory=1,bgsave失败概率下降,但mem_fragmentation_ratio持续>2.0仍需告警——说明内存碎片已影响效率
真正难处理的是“内存缓慢爬升+小幅度抖动”的场景,这时候光看瞬时百分比没用,得结合used_memory_peak和增长斜率做趋势预测,那已经超出简单脚本范畴了。


















