场景:无实时性要求
其他方案:
-
使用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
}