Redis bgsave 线上分析

redis在做RDB(快照)持久化时会fork一个子进程出来,把内存中的数据持久化到磁盘的rdb文件。

线上有个接口响应延迟P99波动较大,后对其进行了优化。响应延迟折线图如下:

优化完成后,P99趋于平稳,平均在70ms左右。

1 思考接口的执行过程

这个接口一共会经过三个服务,最终返回给客户端。执行流程如下:

 

 

按照箭头所示流程,先访问服务1,服务1的结果返回给接口层,在请求服务2,服务2请求服务3,然后将结果返回给接口层。

2 分析

然后分别观察了服务1、服务2、服务3,主要观察的指标如下:

  • 服务对外响应延迟
  • CPU负载
  • 网络抖动

观察后,服务2和服务3的这几个指标都没啥问题。

服务2的对外响应延迟波动情况与接口的波动颇为相似,再针对服务2分析。服务2是个IO密集型的服务,平均QPS在3K左右。

主要的几个IO操作包括:

  • 单点Redis的读取
  • 集群Redis的读取
  • 数据库的读取
  • 两个http接口的拉取
  • 一次其他服务的调用

集群Redis的响应很快,平均在5ms左右(加上来回的网络消耗),数据库在10ms左右,http接口只有偶尔的慢请求,其他服务的调用也没问题。

最后发现单点的Redis响应时间过长

如图所示,服务2接受到的每次请求会访问三次这个单点redis,这三次加起来有接近100ms,然后针对这个单点redis进行分析。

发现这台redis的CPU有如下波动趋势

基本上每一分钟会波动一次。

马上反应过来是开启了bgsave引起的(基本1分钟bgsave一次),因为之前有过类似的经验,就直接关掉bgsave再观察

3 解决方案

线上的bgsave不能一直关闭,万一出现故障,会造成大量数据丢失。

具体方案如下:

  • 先开启这台机器的bgsave
  • 申请一台从服务器,并从这台机器上同步数据
  • 同步完成后,主节点关闭bgsave,从节点开启bgsave

这样一来,主节点的读写不再受bgsave影响,同时也能用从节点保证数据不丢失。

4 bgsave引起CPU波动原因探索

首先要说一下bgsave的执行机制。执行bgsave时(无论以哪种方式执行),会先fork出一个子进程来,由子进程把数据库的快照写入硬盘,父进程会继续处理客户端的请求。

所以在平时没有bgsave的时候,进程状态如下:

bgsave时,进程状态如下:

最上面CPU占用100%的就是fork出来的子进程,在执行bgsave,同时他完全独占了一个CPU(上面的红框)。

所以得出结论,这个CPU的波动是正常的,每一个波峰都是子进程bgsave所致。

 

RDB为了将数据持久化到硬盘,需要经常fork一个子进程出来。数据集如果过大的话,fork()的执行可能会非常耗时,如果数据集非常大的话,可能会导致Redis服务器产生几毫秒甚至几秒钟的拒绝服务,并且CPU的性能会急剧下降。

这个停顿的时间长短取决于redis所在的系统,对于真实硬件、VMWare虚拟机或者KVM虚拟机来说,Redis进程每占用1个GB的内存,fork子进程的时间就增加10-20ms,对于Xen虚拟机来说,Redis进程每占用1个GB的内存,fork子进程的时间需要增加200-300ms。

但对于一个访问量大的Redis来说,10-20ms已经是很长时间了(我们的redis占用了10个G左右内存,估计停顿时间在100ms左右)。

 

转载:https://zhuanlan.zhihu.com/p/89248752

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值