Lua Redis使用下划线排序

我在我的两台Ubuntu服务器上发现表格以不同的方式排序的问题。我在redis-cli工具中执行以下命令。这是服务器1:

127.0.0.1:6379> eval "local a = {'_mcat:banner','for_meta:1','_size:300x250','_mtype:html', 'axx:1'};table.sort(a);return a;" 0
1) "_mcat:banner"
2) "_mtype:html"
3) "_size:300x250"
4) "axx:1"
5) "for_meta:1"

这是服务器2:

127.0.0.1:6379> eval "local a = {'_mcat:banner','for_meta:1','_size:300x250','_mtype:html', 'axx:1'};table.sort(a);return a;" 0
1) "axx:1"
2) "for_meta:1"
3) "_mcat:banner"
4) "_mtype:html"
5) "_size:300x250"

正如您所看到的,问题在于排序处理'_'字符。我已经尝试升级redis和gcc的版本,行为在服务器之间没有改变。测试的Redis版本:2.8.4, 2.8.19, 4.0.2,gcc版本:4.8.2。运行'local'在两台服务器上返回相同的值:

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

在Python中执行相同的代码,在两台机器上都起作用:

>>> sorted(['_mcat:banner','for_meta:1','_size:300x250','_mtype:html', 'axx:1'])
['_mcat:banner', '_mtype:html', '_size:300x250', 'axx:1', 'for_meta:1']

也许有人对下一步要尝试的有建议?谢谢。

编辑

在两个服务器上运行:

eval "local a = {'_mcat:banner','for_meta:1','_size:300x250','_mtype:html', 'axxx:2'};table.sort(a, function(a,b) return a<b end);return a;" 0

产生与table.sort(a)(因此在服务器之间不同)一致的结果,但是看一下这个:

在服务器1上:

127.0.0.1:6379> eval "local a;if 'axxx:2'>'_mcat:banner' then a=1 else a=0 end;return a;" 0
(integer) 1

127.0.0.1:6379> eval "local a;if 'a'>'_' then a=1 else a=0 end;return a;" 0
(integer) 1

在服务器2上:

127.0.0.1:6379> eval "local a;if 'axxx:2'>'_mcat:banner' then a=1 else a=0 end;return a;" 0
(integer) 0
127.0.0.1:6379> eval "local a;if 'a'>'_' then a=1 else a=0 end;return a;" 0
(integer) 1
点赞
用户1442917
用户1442917

由于table.sort是在Lua中使用快速排序实现的(src/ltablib.c),且对于字符串而言,比较最终归结为strcoll调用,因此很难确定下划线何处出错。我建议添加一个自定义排序函数来查看是否改变了结果(table.sort(a, function(a,b) return a<b end)),如果仍产生错误的结果,则可以打印出a,b,a<b值来查看错误发生的位置。

2017-11-27 18:37:55
用户730199
用户730199

感谢所有的评论和建议,我仍然不知道发生了什么,但是重新建立服务器起作用了。

2018-01-10 10:32:58