【发布时间】:2018-05-11 01:19:22
【问题描述】:
我在两台 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。运行 locale 在两台服务器上返回相同的值:
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
【问题讨论】:
-
奇怪 - 看看 Redis 中的嵌入式 Lua 引擎,我不明白这是怎么可能的
-
确实很奇怪;也许试试
print('a'>'_', 'ax'>'_m', 'axx'>'_mc', 'axxx'>'_mca')等等看看哪里出了问题。 -
@Paul Kulchenko 'ax' > '_m' 返回 0,从 0 开始。您对我可以如何处理这些信息有什么建议吗?
-
唯一想到的是你没有使用实际的下划线,而是它的一些 unicode 变体,它具有多字节内容,使得第一个字节值小于 'a' , 但第二个字节值大于小写字符,这会产生您看到的结果。如果不是这样,那么也许@ItamarHaber 可以提出一些建议......
-
在两台服务器上运行
eval "return string.byte('_', 1, string.len('_'))"