scan读取匹配的key

场景:无实时性要求

其他方案:

  • 使用List备份ZSET键名,使不同ZSET有了先来后到,但是这个备份的List容易产生大Key问题,拆分成多个Key需要考虑分布均匀等问题,较麻烦;

  • keys会造成阻塞,不考虑。

代码实现:

func TimeOut() {
	time.Sleep(time.Second * 3)
	defer func() {
		if r := recover(); r != nil {
			logger.Error("Recovered in ", r)
		}
	}()
	for {
		count := int64(500)
		start, err := GetKeys(0, count)
		if err != nil {
			logger.Error(err)
			continue
		}
		for start > 0 {
			logger.Debug(start)
			start, err = GetKeys(start, count)
			if err != nil {
				logger.Error(err)
				continue
			}
		}
        //游标为0说明已经全部检查了一遍,故退出
		//执行一次之后间隔2小时
		time.Sleep(time.Hour * 2)
		continue
	}
}
func GetKeys(start int64, count int64) (int64, error) {
	values, err := redis.Do("SCAN", start, "match", "键名规则*", "count", count).Values()
	if err != nil {
		return start, err
	}
	var keys []string
	for _, item := range values {
		if data, ok := item.([]interface{}); ok {
			for _, item2 := range data {
				str := string(item2.([]uint8))
				keys = append(keys, str)
			}
		}
		if data, ok := item.([]uint8); ok {
			str := string(data)
			start = int64(str)
			if start == 0 {
				return start, nil
			}
		}
	}
	if len(keys) > 0 {
		//todo 处理符合条件的keys
	}
	return start, nil
}

猜你喜欢

转载自blog.csdn.net/qq_37575994/article/details/128011136