Lua Cjson性能问题

941 views
Skip to first unread message

黄川

unread,
Dec 24, 2015, 1:27:19 PM12/24/15
to openresty
我使用Lua Cjson来解析request中的数据,提取其中一个field来做proxy,但好像Lua cjson的性能非常不好。

我用一个简单的json {"id": xxx},QPS 20s 可以达到17303

$ wrk -t6 -c12 -d20s --timeout 2s https://127.0.0.1:20000/dev
Running 20s test @ https://127.0.0.1:20000/dev
  6 threads and 12 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   726.19us  737.91us  26.40ms   94.03%
    Req/Sec     2.91k     1.68k    7.74k    78.08%
  348170 requests in 20.01s, 62.74MB read
Requests/sec:  17403.42
Transfer/sec:      3.14MB

还一个稍微复杂一点地"{\"id\": xxx,\"app\": {\"bundle\": \"749124884\",\"cat\": [\"IAB3\",\"utiliti0es\"]}}",QPS就只有138了, CPU

Running 20s test @ https://127.0.0.1:20000/dev
  6 threads and 12 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    18.33ms    4.01ms  42.38ms   69.53%
    Req/Sec   108.47     20.53   161.00     67.58%
  12975 requests in 20.01s, 2.34MB read
Requests/sec:    648.31
Transfer/sec:    119.63KB


感觉这个差距有点悬殊,大家有没有遇到过这样的问题?
准备用systemtap去看看cpu花在哪呢,如果大家有其他profile的方法也建议下,谢谢!

Yichun Zhang (agentzh)

unread,
Dec 24, 2015, 2:00:21 PM12/24/15
to openresty
Hello!

2015-12-24 10:27 GMT-08:00 黄川:
>
> 感觉这个差距有点悬殊,大家有没有遇到过这样的问题?
> 准备用systemtap去看看cpu花在哪呢,如果大家有其他profile的方法也建议下,谢谢!
>

嗯,建议使用 systemtap 或者 perf 绘制出 on-CPU 火焰图来进行分析。

值得一提的是,CloudFlare 的 lua-resty-json 库里的 JSON 解析器效率通常比 lua-cjson 高很多:

https://github.com/cloudflare/lua-resty-json

我们在生产上使用这个库而不是 lua-cjson. 仅供参考。

Regards,
-agentzh

黄川

unread,
Dec 27, 2015, 4:16:32 AM12/27/15
to openresty
lua-resty-json 如何加入openresty?我把它放在bundle底下,然后编译,但在其他文件里面require "json_decoder"找不到。

Yichun Zhang (agentzh)

unread,
Dec 27, 2015, 12:47:22 PM12/27/15
to openresty
Hello!

2015-12-27 1:16 GMT-08:00 黄川:
> lua-resty-json 如何加入openresty?我把它放在bundle底下,然后编译,但在其他文件里面require
> "json_decoder"找不到。
>

不是这么搞的。正确的安装方法是(假设你已安装了 OpenResty,并使用默认的 prefix,即 /usr/local/openresty):

cd /path/to/lua-resty-json/
make
cp json_decoder.lua /usr/local/openresty/lualib/
cp libljson.so /usr/local/openresty/lualib/

然后直接在你的 Lua 代码里面 require() 就好了。

Regards,
-agentzh

黄川

unread,
Dec 27, 2015, 1:51:19 PM12/27/15
to openresty
明白了,多谢春哥!!

wd

unread,
Dec 30, 2015, 6:38:59 AM12/30/15
to open...@googlegroups.com
有比较结果了么?和 cjson 比。。

--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html

YuanSheng Wang

unread,
Dec 30, 2015, 7:43:26 AM12/30/15
to open...@googlegroups.com
qq 群里有人做了简单的压力测试,json_decoder 的 decode 过程大约有 20% 性能提升。这东西肯定和测试用例有关系,不可全信,仅供参考。

你可以同样写个小例子压测一下,如果有生产环境 json 数据就更好了。



--

YuanSheng Wang
---------------------------------------
OpenResty lover ^_^

黄川

unread,
Dec 30, 2015, 6:35:14 PM12/30/15
to openresty
我用ngx-sample-lua-bt发现我的问题不是json parsing的问题,因为两个decoder on-cpu的消耗都很少<0.6%。。

然后注意top cpu只有<10%,所以我觉得可能是cosocket send或receiveutil的synchronize call的问题,不过因为我的sample-bt-off-cpu kerneldebuginfo没弄好还没画出off-cpu的图去验证,想用ngx-lua-tcp-recv-time.sxx去看看cosocket connection传输时间,总是说"No samples found so far"。。

Shuxin Yang

unread,
Dec 30, 2015, 8:06:24 PM12/30/15
to open...@googlegroups.com

On 12/30/2015 04:43 AM, YuanSheng Wang wrote:
qq 群里有人做了简单的压力测试,json_decoder 的 decode 过程大约有 20% 性能提升。这东西肯定和测试用例有关系,不可全信,仅供参考。

It is. The json_decoder is trying to improve the performance of parsing string. So, if the json is string
intensive, json_decoder will see some improvement.

Again, depends on the input, for medium-sized (say, 4k chars), string-intensive json see about 30% improvement;
The bigger the input, the higher speedup.  I  came across a case before where the input string-intensive jason is
having about 10k char, json_decoder see about 3 times speedup.

To squeeze more performance out of lua_decoder, please get rid of the white-spaces between elements.
White-space incur branch mis-prediction, and likely incur some 10% degradation.

Parsing floating-point is bit slow compared to other jason decoders. For simplicity, I just call libc to
parse floating-point number. Note that some jason decoders are *incorrect* in parsing floating point,
as they are completely ignore the rounding error issue, which is a big issue if we are dead serious about
precision.

Sorry for not replying in Chinese,  my SCIM somehow does not work recently.

Best Regards
Shuxin

YuanSheng Wang

unread,
Dec 30, 2015, 8:49:27 PM12/30/15
to open...@googlegroups.com
great thanks for your power reply. i'll copy it to our QQ talking group, let more guys know it.

thanks again.

山鹰-China

unread,
Dec 30, 2015, 10:46:56 PM12/30/15
to OpenResty Mail list
在luajit-2.1环境下resty.json比lua-cjson要快。具体可以参考http://bbs.iresty.com/topic/35/cjson-lua-resty-json-%E6%80%A7%E8%83%BD%E5%B0%8F%E6%B5%8B%E8%AF%95

瞿秋丰

unread,
Dec 30, 2015, 10:47:16 PM12/30/15
to openresty
报错如下

2015/12/31 11:35:59 [error] 20589#0: *9379 lua entry thread aborted: runtime error: error loading module 'libljson' from file '/usr/local/webserver/lualib/libljson.so':
/usr/local/webserver/lualib/libljson.so: undefined symbol: luaopen_libljson
stack traceback:
coroutine 0:
[C]: in function 'require'
content_by_lua(nginx.conf:57):2: in function <content_by_lua(nginx.conf:57):1>, client: 122.224.99.166, server: xxxx, request: "GET /test HTTP/1.1", host: "xxxx"

代码是

 location /test
 {
               default_type text/plain;
               content_by_lua '
                  local cjson = require "libljson"
               ';
  }

在 2015年12月28日星期一 UTC+8上午2:51:19,黄川写道:

瞿秋丰

unread,
Dec 30, 2015, 11:12:58 PM12/30/15
to openresty, eagle...@hotmail.com
原来是这样  

 location /test
            {
               default_type text/plain;
               content_by_lua_block{
                  local ins = require("json_decoder").new()
                  local d3  = ins.decode
                  local obj = d3(ins,'{"name":"qqf"}')
                  ngx.say(obj.name)
               }
            }


在 2015年12月31日星期四 UTC+8上午11:46:56,山鹰-China写道:

Yichun Zhang (agentzh)

unread,
Dec 31, 2015, 12:47:10 AM12/31/15
to openresty
Hello!

2015-12-30 15:35 GMT-08:00 黄川:
> 我用ngx-sample-lua-bt发现我的问题不是json parsing的问题,因为两个decoder on-cpu的消耗都很少<0.6%。。
>

把这工具生成的火焰图贴出来看一下?

> 然后注意top cpu只有<10%,所以我觉得可能是cosocket send或receiveutil的synchronize

不会,因为 cosocket 发起的系统调用都使用了 100% 非阻塞模式,因此不可能有 off-CPU 类型的 I/O 阻塞发生。

你的 nginx worker 进程的 CPU 使用率压不上去?你有使用 ab 这样的工具压测吗?记得开启 -k 选项哈,以免把临时端口耗尽。

另外,记得随时检查你的 nginx 的错误日志,避免 nginx 把主要时间都浪费在刷错误日志上面。当然,你的 error_log
配置指令也不要配置太高的错误过滤级别,一般用 warn 或者 error 就好了。

> call的问题,不过因为我的sample-bt-off-cpu
> kerneldebuginfo没弄好还没画出off-cpu的图去验证,

应该画出 off-CPU 火焰图来看。这样一目了然。

另外,使用 strace 命令在系统调用级别也可能看出些端倪,只不过不如 off-CPU 火焰图那么清楚和全面罢了。

> 想用ngx-lua-tcp-recv-time.sxx去看看cosocket
> connection传输时间,总是说"No samples found so far"。。
>

那说明你检查的那个 worker 进程也没什么 cosocket 调用。

由于你已确认和 JSON 解析无关,那么应该另开一个邮件主题进行讨论了。再继续讨论下去就跑题更远了 :)

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