https://github.com/openresty/luajit2/issues/60
以前 openresty 处理 大量字符串时, 如果出现了大量hash冲突,性能是大幅下降的。而且hash值是没有进行 O(n) 级别的运算的, 前半截变化少的长字符串(>127)冲突率不低。
用openresty做大量业务开发时,缓存字符串数量是可以达到 几十万的。当冲突堆积出现性能雪崩时, 其实没有好的办法解决。要把全部长字符串变成 127 以内的字符串组, 难度挺大的(json库都没法用)。不稳定的性能不能让程序员安心, 线上出现了这种情况, 就很难解决。
使用issue中的样例:对比了一下修复后的情况:
调整了一行: local cnt = tonumber(arg[1]) or 1000
resty 1.17.8.2 luajit(最新)
`
[nz@nz-PC test]$ resty t.lua 20000
18.302767
0.0017530000000008 -- 倒数第四个字符串生成时间
0.0018139999999995
0.0017220000000009
0.0022369999999974
total:18.310301
[nz@nz-PC test]$ ./luajit t.lua 20000
0.019561
0.000102
2.9999999999995e-06
2.9999999999995e-06
8.0000000000011e-06
total: 0.019678
[nz@nz-PC test]$ ./luajit t.lua 200000
0.242339
3.5000000000007e-05
6.000000000006e-06
8.9999999999812e-06
3.0000000000308e-06
total: 0.242395
[nz@nz-PC test]$ ./luajit t.lua 2000000
2.183687
2.6000000000082e-05
2.4999999999942e-05
3.0000000004193e-06
1.9999999993914e-06
total: 2.183746
`
上游luajit 修复后快了很多,以后可以开心的使用 字符串了, receiveany也不用小心冲突了。
我另外使用openresty的luajit2编译了 集成 wyhash32的版本, 直接使用wyhash32效果也不错:
`
[nz@nz-PC test]$ ./luajit-or-wyhash t.lua 200000
0.168568
2.1999999999966e-05
3.0000000000308e-06
2.4999999999997e-05
2.000000000002e-06
total: 0.168622
[nz@nz-PC test]$ ./luajit-or-wyhash t.lua 2000000
2.211359
3.0000000000641e-05
5.9999999999505e-06
3.9999999996709e-06
3.9999999996709e-06
total: 2.211406
`
|字符串数组大小| resty 1.17.8.2| luajit(e9af1abe)|luajit2-or-wyhash|
|:----|:----|:----|:----|
|2000|0.15s|0.0012|0.0017|
|20000|18s|0.019|0.016|
|200000|2390.20|0.24|0.17|
|2000000|-|2.15|2.24|
希望openresty 尽早合并修复。:)