技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统运维 --> 本周扑火之 redis 不给力

本周扑火之 redis 不给力

浏览:4717次  出处信息

    Social Graph 高速接口,当前我们使用 Redis 存储。但在实现的过程中,发现了诸多的问题。

    48G 内存的机器上部署了 2 个 Redis 进程,一个 Redis 占用超过 21 G 内存后,在快速写入的过程中同时进行一次 bgsave ,就将机器给弄挂了(微博上的直播)。我们对 Redis 的监控远不如对 Mysql 之类的完善,以至于 Redis 机器假死,居然没有触发任何的报警。

    在经过几天的 debug 后,终于找到了问题所在,复杂的上线流程:源码 svn 合 trunk,发布 jar 包到二进制 svn,配置文件按 IDC 配置,打 tag,上线,发布,终于有一个小小的地方没有控制住,没有进行最终的确认,导致发到线上的配置文件是源码目录中的测试配置,导致 redis hash 出错。而严重缺乏的监控,也没能发挥“最后一道防线”的作用,任由问题越演越烈(微博上的直播)。

    按说找到了问题所在,修复起来就很容易了。但 billion 级别的数据,重新初始化,远比想象的复杂。从上周五开始重新灌数据,周六在家习惯性的用 iphone 登陆看 log 。一看吓一跳:按那个速度计算,重新初始化需要一个月才能完成。而第一次初始化,才花了几十个小时啊。

    首先怀疑是资源的问题:打电话找运维,确认 redis 没有问题,数据库没有问题,queue 队列没有问题。那就是程序的问题了。用 Btrace 一层一层的跟踪,最后定位在 jedis.hset 和 jedis.hdel 上:一次 hset 或 hget 居然需要超过 100 ms (微博上的记录)。周一到单位,给代码加了详细的时间 log ,也印证了周末 Btrace 的结果。这是为什么呢?

    还是怀疑 redis 服务器的问题。写了一个简单的压力测试代码去压测试用的redis,在本机上运行,果然每秒才 4000 来次 hget、hset 。可是拿到服务器上一跑,轻松的就到了 4 万多次。所以本机上慢,应该是网络带宽的原因。

    接下来只能怀疑是程序代码的问题。但在测试环境下回滚版本,换客户端库,各种手段用完都找不到问题之后,只能将目光转向线上环境。 

    直接用压力测试代码压线上服务器,果然也慢。继续看 log ,似乎慢的请求有一个共性:某个时间点,几十个请求的耗时是一样的,都是类似 127ms,132ms 这样的。如果是真实的处理耗时,不应该会如此雷同才对,那么就应该是排队等待耗时了。这一批请求应该是同时发起的,因为某种原因,一同在某个地方排队,等轮到它们的时候,真实的处理耗费的时间连 1 ms 都不到,所以在 log 里看来,耗时如此相似。接下来的问题就是,为什么会排队?在哪排队?后面一个问题比较好回答,Redis 是单线程的,按照网络接收到的包的顺序处理请求,前一个请求没有处理完之前,后面的请求都在 server 的 tcp/ip buffer 里排队,等待处理。那剩下的就只有一个问题了:为什么会有排队现象?

    仔细看业务代码,终于找到一个可疑的地方:hgetAll 。难道是一个 hgetAll 堵住了后面所有的请求?压测的脚本一般都只压 get,set,顶多也就试试 hget,hset,肯定不会压 hgetAll 这么变态的命令的。而用 strace 查看 redis server 的状态,也只能看到网络调用耗时。那么也就只能这么解释了:hgetAll 命令占用了大量的网络带宽,导致它完成之前,其它的命令的回包都在 tcp buffer 里面堵着了。

    试着修改了一下业务处理逻辑,减少了部分冗余的 hgetAll 调用,果然速度有所提升。虽然还是没有第一次的时候快,但好歹升到了一个可接受的范围了。

    接下来,就是重构 redis 相关的代码,让下次的 debug 不至于这么被动。有时间顺便在测试环境下重现一下这种情况,以确定自己的怀疑。

建议继续学习:

  1. redis源代码分析 - persistence    (阅读:31140)
  2. Redis消息队列的若干实现方式    (阅读:10703)
  3. 基于Redis构建系统的经验和教训    (阅读:9283)
  4. 浅谈redis数据库的键值设计    (阅读:8286)
  5. redis运维的一些知识点    (阅读:7417)
  6. redis在大数据量下的压测表现    (阅读:7379)
  7. Redis和Memcached的区别    (阅读:6776)
  8. Redis作者谈Redis应用场景    (阅读:6564)
  9. redis 运维实际经验纪录之一    (阅读:6470)
  10. 记Redis那坑人的HGETALL    (阅读:6318)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1