【问题标题】:Sorting with underscore in Lua Redis在 Lua Redis 中使用下划线排序
【发布时间】: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'&gt;'_', 'ax'&gt;'_m', 'axx'&gt;'_mc', 'axxx'&gt;'_mca') 等等看看哪里出了问题。
  • @Paul Kulchenko 'ax' > '_m' 返回 0,从 0 开始。您对我可以如何处理这些信息有什么建议吗?
  • 唯一想到的是你没有使用实际的下划线,而是它的一些 unicode 变体,它具有多字节内容,使得第一个字节值小于 'a' , 但第二个字节值大于小写字符,这会产生您看到的结果。如果不是这样,那么也许@ItamarHaber 可以提出一些建议......
  • 在两台服务器上运行eval "return string.byte('_', 1, string.len('_'))"

标签: sorting lua redis locale


【解决方案1】:

鉴于 table.sort 是在 Lua 本身中使用快速排序 (src/ltablib.c) 实现的,并且对于字符串,比较归结为 strcoll 调用,很难说下划线可能出错的地方。我会尝试添加一个自定义排序函数来查看这是否会改变结果 (table.sort(a, function(a,b) return a&lt;b end)),如果它仍然产生不正确的结果,那么您可以打印 a, b, a&lt;b 值以查看哪里出错了。

【讨论】:

  • 感谢您的建议,我尝试了更多的东西,看看编辑的问题
  • 似乎语言环境甚至可以更改下划线的排序顺序,所以可能就是这样。有关示例,请参见 stackoverflow.com/a/43081689/5751627
【解决方案2】:

感谢所有 cmets 和建议,我仍然不知道到底发生了什么,但重建服务器成功了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 2018-01-04
    • 2023-04-04
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    相关资源
    最近更新 更多