队列堵塞问题总结
2017-06-20
早上十点到公司运维, 打电话说队列堵了
listen:room:entry:queue
主播房间进出事件队列 堵了十几万条 ....
原因是app开始推广, 大量用户进出主播房间, 前几天无用户量队列阻塞不明显, 设计每秒3000 Lpush .
生产环境: 单一php脚本Rpop一次加处理逻辑0.0017秒, 每秒redis Qps在500到600之间,
而内网环境每秒Qps能达到3600... 无语了redis 31机房Qps受限制每秒Qps最大700-800 ...
单一php脚本Rpop构建单一redis实例明显达不到3000Qps.
应急处理办法:
要来一台Qps 3000+的 33机房 redis , 写脚本从31机房redis 队列中Rpop 在Lpush 到 33机房redis中队列, 当然这个新写的脚本需要启动多个进程.
原有脚本读取33机房redis队列, 脚本3000+/秒的Rpop 快速消掉队列中堵塞的信息, 好吧问题告一段落;
原有脚本pop 没有push 快 造成大量堵塞, 设计之初就是使用单一进程,但受31 机房redis Qps限制将脚本改为支持多进程(业务逻辑调整).
23:50分计划将队列切回来, 但发现33机房redis 队列中堵了4000多万条......(:_:)
查找原因为写的转发脚本pop到空也打了过来.
原有脚本中的处理 pop 到空 usleep(100000) , 调用速度降为10次/秒 ......
解决办法, 现将脚本中 usleep(100000) 注释. 再讲中转数据脚本关闭, 将改动后脚本启了33个进程, 用了4分钟多种 这才将4000多万阻塞数据打掉...
实际上队列中的数据都是用于统计结算使用, 堵塞成这个样子这些数据实际上已经没用了.
用户目前还是无感的, 因为结算功能还尚未发布, 但这也算是一次经验教训, 使用队列的生产环境下,还需要考虑机房redis Qps限制, 出现问题不能临时解决后不做监控,这样会造成更大的问题发生, 一开始十几万觉得不少,但到最后4000多万阻塞, redis内存都快打满了.
总结下教训:
非特殊场景 脚本一定要支持多进程, 生产环境需要测试redis的Qps限制