关于redis:故障分析-bgsave-导致-redis-定期卡顿案例一则

39次阅读

共计 1745 个字符,预计需要花费 5 分钟才能阅读完成。

作者:任坤

现居珠海,先后负责专职 Oracle 和 MySQL DBA,当初次要负责 MySQL、mongoDB 和 Redis 保护工作。

本文起源:原创投稿

* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


1、背景

线上有套 redis 主从,版本 4.0,开发埋怨说常常会呈现周期性卡顿。

利用日志显示每隔 10 多分钟呈现一次,一个一般调用就须要执行 1s 左右,而后主动复原,get/set 均受影响

2、诊断

查看 redis qps 和 cpu 监控,均未发现有用线索。

登录 redis 查看 slowlog,也没有吻合工夫点的慢查问。

evicted_keys 指标始终是 0,expired_keys 数量尽管很多,然而始终没有显著稳定,不太可能是驱赶过期键导致。

经组里共事揭示留神到 latest_fork_usec 指标,执行一次靠近 1s 左右,大概每 15 分钟触发一次 bgsave,和利用呈现慢查问的频率大抵吻合,当初初步认定是 redis 实例定期 bgsave 导 致的利用卡顿。

在相当长的一段时间内,我始终认为 redis 的 bgsave 衍生出 1 个子过程并且采纳 copy-on- write 机制,不会对 redis 自身有太多影响,顶多落盘时占用点 IO 资源而已。

潜在瓶颈点呈现 fork() 调用上

Under Linux, fork() is implemented using copy‐on‐write pages, so the 
only penalty that it incurs is the time and memory required to duplicate the 
parent's page tables, and to create a unique task structure for the child. 

如果父过程的页表比拟大,fork() 耗时就会相应缩短,且 redis 采纳了单工作过程模型,fork() 执行期间会阻塞所有用户申请。

以后 redis 实例的 RSS 曾经达到了 16G

页表大小 33M

cat /proc/8844/status | grep ‐i pte
VmPTE: 33840 kB

采纳 strace 跟踪一下 fork() 耗时,在 glibc 里 fork 的调用实际上映射到了更底层的 clone 零碎 调用,因指定 -e trace=clone

# strace ‐p 20324 ‐e trace=clone ‐T 
... 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHL D, child_tidptr=0x7f409d771a10) = 30793 <1.013945> 
...

于此对应的 redis 监控指标为

latest_fork_usec:1014778 

两者吻合,由此能够确认是 redis 定期 bgsave 引发的。

最简略的办法是禁用 bgsave,但这种行为有很大的危险,一旦主库被误杀且在主从切换前又被迅速拉起,会导致 redis 数据全副失落。

查看 redis 的内存利用率,存在很重大的内存碎片,

used_memory_human 8.7G
......
used_memory_rss_human 16.1G 

这套 redis 马上就要迁徙,新环境实例的 RSS 只有 8.8G,latest_fork_usec 指标也降落达到了 0.25s 左右,和开发确认后能够满足利用需要,迁徙后利用的定期卡顿景象有了很显著的缓解。

redis 4.0 引入了碎片主动回收性能,由参数 activedefrag 调控,默认敞开。迁徙后对老 redis 开启了 activedefrag(其余参数放弃默认值),最终 used_memory_rss_human 固定在 11G 左右,latest_fork_usec 在 0.76s 左右。新环境当前也可能会遭逢重大内存碎片,届时要么开启 activedefrag,要么在保护时间段重启实例,后者成果显然更好一点。

3、小结

咱们线上 redis 主从都开启了 bgsave,之前始终漠视了 bgsave/fork() 可能引发的性能稳定,最好的解决办法就是管制单个 redis 的内存下限,如果业务端无奈瘦身能够思考 redis cluster 或者设置 maxmemory。当前如果遇到了 redis 定期卡顿景象,能够优先从 latest_fork_usec 监控指标动手。

正文完
 0