lua-resty-redis查询/建立连接超时,附火焰图分析

162 views
Skip to first unread message

zhong...@gmail.com

unread,
May 26, 2016, 11:48:42 AM5/26/16
to openresty
HELLO! 公司线上采用了openresty1.9.1作为后台, 最近在压力测试的情况下,遇到了一些问题。
场景如下:
请求中携带cookie作为认证凭据,在lua逻辑代码中使用cookie,到redis中查询用户信息;验证通过后,从mongodb中取出数据,返回给客户端。也就是说,每个请求,都需要做两个操作,读redis,认证通过则接着读mongodb。

redis版本为3.0.2, 硬件配置为2核8G内存,带宽100M, 操作系统Ubuntu14.04,使用官方lua-resty-redis作为驱动;
mongodb版本为3.2.0, 硬件配置为4核8G内存,带宽100M, 操作系统Ubuntu14.04,使用lua-resty-mongol[https://github.com/bigplum/lua-resty-mongol]作为驱动;

使用wrk进行压力测试,硬件配置为4核8G内存,带宽100M, 操作系统Ubuntu14.04,执行命令为: wrk -t2 -c2000 -d5m -T10s --script=scripts/interface.lua --latency http://10.xx.xx.xx, interface.lua脚本会循环选择接口进行测试。

测试发现:
1. 固定connection为2000,即wrk -c 2000, 如果某个接口的mongodb查询返回值增大,则该接口在火焰图中所占的比例也会增加(对比图1和图2中device接口所占比例),当查询返回值增加到1KB左右,lua-resty-redis查询就会超时。

2. 保持mongodb查询返回值大小不变,则connection增加到5000时,lua-resty-redis返回查询超时错误。

测试的时候,openresty的4核CPU使用率都到100%,但load average很低,都还不到1,内存使用率不到50%;mongodb和redis的load average也都不到1,内存使用率都不到50%;

想问大家:
1. 既然openresty是nonblock的,为什么mongodb的返回值大于1k时,会导致redis查询超时?
2. 这样情况下,应该考虑从哪些方面进行样优化?

谢谢
图1.svg
图2.svg

Yichun Zhang (agentzh)

unread,
May 27, 2016, 3:40:12 PM5/27/16
to openresty
Hello!

2016-05-26 8:48 GMT-07:00 <zhong...@gmail.com>:
> 测试发现:
> 1. 固定connection为2000,即wrk -c 2000,
> 如果某个接口的mongodb查询返回值增大,则该接口在火焰图中所占的比例也会增加(对比图1和图2中device接口所占比例),当查询返回值增加到1KB左右,lua-resty-redis查询就会超时。
>

从你提供的 Lua 级别的火焰图上看,你使用的第三方的 lua-resty-mongol 库的效率确实很差。特别地,这个库的
resty.mongol.ll 模块中的 le_uint_to_num 函数占用了绝大部分的 CPU 时间。最简单地做法是针对这个 Lua
函数进行优化。

> 想问大家:
> 1. 既然openresty是nonblock的,为什么mongodb的返回值大于1k时,会导致redis查询超时?

OpenResty 的 I/O 是非阻塞的,但如果是 CPU 计算过于密集,显然也会阻塞 nginx 的事件循环。

另外,建议同时绘制出 C 级别的火焰图,以确认没有 Lua 以外的瓶颈。

> 2. 这样情况下,应该考虑从哪些方面进行样优化?
>

请见上面的根据你的 Lua 火焰图所给出的建议。

Regards,
-agentzh
Reply all
Reply to author
Forward
0 new messages