优化通过节点在redis中查询多个键

时间:2014-04-01 21:30:22

标签: node.js redis node-redis

我在以下格式的redis中维护了某个键

identifier:username:userid:categoryname

例如:

Blacklist:tomhanks:12345:movies
Blacklist:tomhanks:12345:music
Blacklist:micaheljordan:23456:sports
Blacklist:micaheljordan:23456:movies

现在有时我可以使用用户名,在某些情况下我也可以使用userid。但后来我不知道哪一个可用。根据API请求,我可以使用其中任何一个。所以我需要查询两次 - 一次使用用户名 - 其次是用户ID。

例如: KEYS Blacklist:tomhanks:* & KEYS Blacklist:*:12345:* 然后组合结果并相应地将从其他API获取的类别列入黑名单。

我使用nodejs来查询这个redis实例,所以我决定在节点js中使用multi exec而不是查询它两次

根据此页node redis github example for multi command上的示例,我以下列格式查询redis实例

client.multi([
    ["keys", "Blacklist:tomhanks:*"],
    ["keys", "Blacklist:*:12345:*"]
]).exec(function (err, replies) {
    console.log(replies.toString());
});

但最近我在redis中检查了slowlog,我在列表的顶部找到了exec命令,还有一些查询超时。虽然KEYS的数量只有10000个。

我也间歇性地收到console.log消息node_redis: no callback to send error: ERR EXEC without MULTI

POA:

  1. 使用以下格式的集而不是KEYS KEY: Blacklist:tomhanks -> movies, music KEY: Blacklist:123456 -> movies, music
  2. 或以某种方式重组第二个密钥Blacklist:*:12345:*,它有2个通配符,因此相对较重 建议的结构将是 Blacklist:tomhanks:movies Blacklist:tomhanks:music Blacklist:12345:movies Blacklist:12345:music
  3. 根据warning posted on this page about KEYS

    Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using sets.

    使用SETSKEYS更好吗?

1 个答案:

答案 0 :(得分:0)

永远不要使用KEYS命令它是否完全阻止整个数据库(Redis有一个用于处理命令的工作线程)来响应命令的持续时间(就像任何其他命令一样)。与KEYS的区别在于它一次扫描并返回整个数据集。对于大型数据集,它可能被证明是有问题的。

Redis SCAN命令是你的朋友。 SCAN通过迭代匹配的结果集(支持诸如KEYS的全局匹配)来工作。直到所有结果都被退回。 这种迭代方法允许“公平”。查询大型数据集时的资源分配,因为每次迭代处理较小部分的数据并且“竞争”。与cpu时间的其他命令。

您不必使用SETS来扫描元素(尽管存在SSCAN变体),但它会影响未来(进入群集或保持独立/哨兵模式< / p>