redis scan

栗:

func (s *commentRedisStore) SyncArticleCommentActionChanged() error {
	randomKey, err := utils.GetNO(commonModel.InfoType(89), 0, s.RedisClient)
	sourceKey := utils.GetArticleCommentActionChangedKey()
	destKey := fmt.Sprintf("%s:%d", sourceKey, randomKey)
	if err != nil {
		logrus.Errorf("get sync action random key err, %v", err)
		return err
	}

	pipe := s.RedisClient.Pipeline()

	pipe.SUnionStore(destKey, sourceKey)
	pipe.Del(sourceKey)
	_, err = pipe.Exec()
	if err != nil {
		logrus.Errorf("sunion store key %s to %s err, %v", sourceKey, destKey, err)
		return err
	}

	// 开始执行同步操作,每次获取 100 个 sn
	var length int64 = 100
	var keys []string
	var cursor uint64 = 0
	var i = 1
	for cursor != 0 || i > 0 {
		i--
		keys, cursor = s.RedisClient.SScan(destKey, cursor, "*", length).Val()
		for _, key := range keys {
			cacheKey := utils.GetCommentSKey(key)
			pipe.HGetAll(cacheKey)
		}

		if cmder, err := pipe.Exec(); err == nil {
			syncArticleCommentAction(cmder)
		}
	}
	pipe.Del(destKey)
	_, _ = pipe.Exec()
	return nil
}

 

用法:

SCAN 命令是一个基于游标的迭代器(cursor based iterator): SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

当 SCAN 命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。

以下是一个 SCAN 命令的迭代过程示例:

redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
    10) "key:7"
    11) "key:1"

redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

在上面这个例子中, 第一次迭代使用 0 作为游标, 表示开始一次新的迭代。

第二次迭代使用的是第一次迭代时返回的游标, 也即是命令回复第一个元素的值 —— 17 。

从上面的示例可以看到, SCAN 命令的回复是一个包含两个元素的数组, 第一个数组元素是用于进行下一次迭代的新游标, 而第二个数组元素则是一个数组, 这个数组中包含了所有被迭代的元素。

在第二次调用 SCAN 命令时, 命令返回了游标 0 , 这表示迭代已经结束, 整个数据集(collection)已经被完整遍历过了。

以 0 作为游标开始一次新的迭代, 一直调用 SCAN 命令, 直到命令返回游标 0 , 我们称这个过程为一次完整遍历(full iteration)。

 

更多:http://doc.redisfans.com/key/scan.html

你可能感兴趣的:(redis)