如何使用golang通过“SCAN”而不是“KEYS”从Redis扫描键

4

这是我的代码

redisPool := redis.NewPool(func() (redis.Conn, error) {
        con, err := redis.Dial("tcp", *redisAddress)
        con.Do("SELECT", 0)
        if err != nil {
            return nil, err
        }
        return con, err
    }, *maxConnections)
    fmt.Println("Redis Connection Establ...!")
    con := redisPool.Get()
    data, err1 := con.Do("scan", "0")
    //data, err1 := con.Do("KEYS", "*")
    if err1 != nil {
        fmt.Println(err1)
    } else {
        fmt.Println(reflect.TypeOf(data))
        fmt.Println(data)
    }

我的输出结果不是字符串


你的代码片段对我有效。在第一次迭代中,它打印了一堆键。 - Nadh
1个回答

16

SCAN命令的特点在于它不仅返回一堆键,而且返回一个“迭代器”号码,您应该将其放入下一次调用SCAN的参数中。 因此,回复的结构可以看作是

[ iterator, [k1, k2, ... k10] ]

你可以通过调用 SCAN 0 开始,并在后续的调用中需要使用 SCAN <iterator>

在redigo中,这样做的方式如下(我的错误处理不正确,但这只是为了展示思路):

// here we'll store our iterator value
iter := 0

// this will store the keys of each iteration
var keys []string
for {

    // we scan with our iter offset, starting at 0
    if arr, err := redis.Values(conn.Do("SCAN", iter)); err != nil {
        panic(err)
    } else {

        // now we get the iter and the keys from the multi-bulk reply
        iter, _ = redis.Int(arr[0], nil)
        keys, _ = redis.Strings(arr[1], nil)
    }
    
    fmt.Println(keys)
    
    // check if we need to stop...
    if iter == 0  {
        break
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接