Redis OOM问题排查

1. 问题描述

看到Redis报了OOM的错误,并且服务响应速度很是慢,页面上丢了不少数据,赶忙起来查看问题。redis

2. 问题排查

咱们的系统架构是双边双活的,两个DC都会有数据写进来,经过API把数据存到数据库(双边数据库有复制),同时写到Redis队列一份(这里把Redis当成MQ来用),而后有个Job从redis队列里面把数据取出来,写到两边,流式地处理数据。对于Redis队列来讲,API是生产者,Job是消费者。此次只是GSB这边的Redis出了问题,致使了单边不可用。数据库

2.1 问题定位

通常Redis里的元数据大小是比较稳定的,出现OOM应该先看队列的大小。果真这个数据队列的size已经远远超过了阈值。咱们先把队列清空了,而后把数据读取从Redis切换到了DB,GSB侧终于能正常工做了。缓存

2.2 进一步跟踪

如今咱们的数据量通常是每秒钟三四百条左右,按理来讲Job的消费速度确定是能跟上的。可是看问题侧(GSB侧)队列大小大体呈每秒钟一百条的速度在递增。看了一下GSB侧Job的log,发现消费速度很不稳定,最慢的时候一秒钟只能处理三四十条。按照Redis官方百万级的QPS,这简直能够用龟速来形容了。接下来咱们来看具体慢在哪里。能够用网络

redis-cli --latency -h `host` -p `port`架构

命令来查看命令的延迟状况,此命令会不断给Redis发ping命令而后统计响应时间。先来看本机延时对比:ide

Primary本机延时性能

GSB本机延时spa

经过在Redis本机上经过latency的对比,发现Primary侧和GSB侧的延时接近一致,一个是0.04ms,一个是0.05ms,看来瓶颈不在Redis自己。再来对比一下从其余机器上连Redis的延时状况:3d

Primary网络延时blog

GSB网络延时

能够看出来,GSB侧的Redis响应速度明显比Primary侧的慢,一个是0.37ms,一个是1.67ms,有近四五倍的差距。可是按理来讲网络速度慢,应该影响到生产者和消费者双方,为何数据仍是能不断堆积呢?这是由于咱们API有四台机器,而Job只有一台机器,致使了消费速度跟不上。

2.3 问题解决

找到了root cause以后,赶忙联系Network Team,被告知GSB侧有一个Network的Incident,估计就是此次问题的元凶了。咱们改了一下代码,检测若是队列大小超过必定的阈值,就删除一部分数据。虽然会致使部分缓存数据的丢失,可是为了避免影响到系统的总体可用性,也只能这么作了。

果真次日,Incident结束了以后,Job的消费速度就恢复正常了。

3. 总结

网络问题致使Redis的响应时间变慢,并且生产者数量比消费者数量多,致使Redis队列数据消费不完,队列堆积,从而OOM。经过此次事件,咱们获得教训:

1. 最好不要用Redis作MQ来用,不然当队列堆积会形成Redis总体不可用,最终致使系统不可用。

2. 生产者和消费者的数量要大体对等,不然要么会出现任务堆积,要么会出现性能资源浪费。

相关文章
相关标签/搜索