【问题标题】:Redis SCAN not giving all matches in NodeJSRedis SCAN 没有给出 NodeJS 中的所有匹配项
【发布时间】:2019-07-06 16:04:12
【问题描述】:

我正在使用带有 redis npm 包的 Node.JS 脚本来检索与模式 animals:toFeed:* 匹配的所有 Redis 键。匹配的示例将是键 animals:toFeed:17ed160f59c5b31caf7e741a4e62cb7785414cd。

使用下面的代码,可以有 10 个匹配项,但代码只会返回几个,例如 2-3。可能是什么问题,我们该如何解决?

使用 Redis 4.0.11、Node.js 8.11.3、redis 2.8.0 npm 包

async function scanAsync(cursor, pattern, results) {
    return redis.scanAsync(cursor, 'MATCH', pattern, 'COUNT', '10')
        .then(function(reply) {
            cursor = reply[0]
            if(cursor === '0') {
                console.log('Scan complete')
            } else {
                console.log('Match #', i)
                let keys = reply[1]
                keys.forEach(function(key, i) {
                    results.push(key)
                })
                return scanAsync(cursor, pattern, results)
            }
        })
}

let keys = []
let prefix = 'animals:toFeed:*'
await scanAsync('0', prefix, keys) 

更新

  1. 重新启动redis。仍有不完整的扫描结果
  2. 删除了与模式匹配的所有键并添加了一些键。现在在进行 SCAN 时一切都返回了。玩了一个小时后,它又开始返回不完整的结果。重复此操作不再能解决问题。

【问题讨论】:

    标签: javascript node.js redis node-redis


    【解决方案1】:

    当光标等于 '0' 时,您忘记将键添加到 results,但您应该始终添加这些键。

    你可以考虑你的代码如下:

    async function scanAsync(cursor, pattern, results) {
        return redis.scanAsync(cursor, 'MATCH', pattern, 'COUNT', '10')
            .then(function(reply) {
    
                let keys = reply[1]
                keys.forEach(function(key) {
                    results.push(key)
                })
    
                cursor = reply[0]
                if(cursor === '0') {
                    console.log('Scan complete')
                } else {
                    return scanAsync(cursor, pattern, results)
                }
            })
    }
    

    【讨论】:

    • 感谢这解决了总是丢失一个键的问题。还将'10' 更改为'1' 使我能够始终如一地获得所有丢失的密钥。你如何决定在这里使用什么号码?在我目前的测试中,只有 1 到 6 个键匹配,但在生产中,这可以从 0 到 1000 个键匹配
    • 这完全取决于您的系统和偏好。较小的count 将需要更多的调用和更长的时间来完成整个扫描迭代。另一方面,较大的count 会更快地完成整个扫描迭代,但会使所有其他调用等待更长的时间。
    【解决方案2】:

    ... 或者您使用redis-async-gen,这样您就不必自己仔细控制所有这些。 (阅读更多关于它的信息here。)

    const redis = require('redis')
    const client = redis.createClient(…)
    const generators = require('redis-async-gen')
    const { keysMatching } = generators.using(client)
    
    const results = []
    for await (const key of keysMatching('test*')) {
      results.push(key)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 2022-06-18
      • 1970-01-01
      相关资源
      最近更新 更多