【问题标题】:Redis Lua Script Return Table and parse objectRedis Lua 脚本返回表并解析对象
【发布时间】:2018-08-05 20:00:04
【问题描述】:

我有问题,

local searchkey=@searchkey
local blockKeys = redis.call('keys', searchkey)
local table = {}
for i = 0, #blockKeys, 1 do
    local seats = redis.call('HVALS', blockKeys[i])
    table[i] = seats
end
return table

我想为 .net obj 解析这个表数据 我使用了 StackExchange.Redis 库和 lua 返回 RedisResult 但 lua 表数据未解析 RedisValue[]

有人有想法吗?

【问题讨论】:

  • 请勿使用KEYS。曾经。说真的,永远不要那样做。在推送中,您可以使用SCAN,但这只能用于管理目的,例如数据库分析工具。首先要做的是不依赖于扫描键空间。一个好的经验法则是使用配置文件将KEYS 命令重命名为KILL_SERVER;现在; Lua 表应该(根据EVAL documentation)映射到多批量回复,因此实际的 shape 应该已经“正常工作”。你拿什么回来?会发生什么?
  • 我不明白,为什么我不使用 keys ,你能给我解释一下吗?因为我检查性能,keysscan好,而且对于table,hvals返回二进制对象so => key, { {key, obj}, {key, obj }}
  • 我已经编辑了我的答案来解决这个问题

标签: c# lua redis stackexchange.redis


【解决方案1】:

RedisResult 是用于未知形状数据的通用包装器。有一些运算符允许您以多种方式解释数据,例如:

RedisResult val = ...

// simple
int asInt = (int)val; // a single integer
string asString = (string)val; // a single string

string[] asStrings = (string[])val; // a table of strings
double[] asDoubles = (double[])val; // a table of doubles

// more structured

var asKeys = (RedisKey[])val; // a table of keys
var asValues = (RedisValue[])val; // a table of values
var asMulti = (RedisResult[])val; // a table of general purpose values

所以您可以可能将其转换为您需要的内容。但是:在脚本中使用 KEYS 是一个大问题,您应该真正改变它。


解决 cmets 的问题:

为什么我不用钥匙,你能解释一下吗?因为我检查性能,keys比scan好,对于table,hvals返回二进制对象so => key, { {key, obj}, {key, obj}}

引用redis documentation

警告:将 KEYS 视为仅应极其小心地用于生产环境的命令。当它针对大型数据库执行时,它可能会破坏性能。此命令用于调试和特殊操作,例如更改键空间布局。不要在常规应用程序代码中使用 KEYS。

每个 redis 实例都有一个用于处理请求的单线程核心。 KEYS 在小型数据库上看起来很好,但有或没有过滤器性能是 O(N),其中 N 是 total 数量数据库中的键,对于大型系统:它可能是灾难性的坏的 - 意思是:需要 10 秒才能返回。通常,redis 操作预计需要毫秒,而当您的KEYS 操作运行时:没有其他方法可以。它完全在这段时间内阻塞了服务器。

您注意到KEYSSCAN 更有效,在某些方面确实如此。 SCAN 的全部意义在于,它允许您将操作作为(可能很长)一系列 小批量 -“扫描前 100 个;现在从那里扫描下一个 100;和下一个 100"。这有很多更多的开销和延迟,并且涉及到服务器的更多往返,但优点是它不会在很长一段时间内阻塞服务器核心。

但是!通常,对其中任何一个的更好方法是使用您希望与数据匹配的集合。假设您有一个大型数据库,并且您对所有 /foo/{whatever} 数据感兴趣。现在;而不是使用KEYSSCAN 来查找这些值,如果您需要 来迭代该系列中的所有键,只需删除所有 是可行的成一套。因此,当您创建/foo/abc 时,您还可以通过sadd/foo/abc 放入set /foo/_keys(或其他;这里没有约定)。现在:要迭代该系列中的所有键,您只需迭代 set /foo/_keys - 这是一个更合适的 API。

【讨论】:

    【解决方案2】:
    var asMulti = (RedisResult[])val;
    foreach (var item in asMulti)
    {
         var asd = (RedisValue[])item;
    }
    

    我的脚本返回表,我认为这是 RedisResult[] 和内部 obj 所以设计

    "key, { {key, obj}, {key, obj}}"

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 1970-01-01
      • 2017-06-26
      • 2021-01-14
      • 2019-07-25
      • 2021-06-27
      • 2022-12-17
      • 1970-01-01
      • 2014-10-08
      相关资源
      最近更新 更多