scan读取匹配的key

2 篇文章 0 订阅
该博客讨论了如何在不使用keys命令避免阻塞的情况下,通过SCAN命令遍历和管理Redis中的ZSET键。文章提到了使用List备份键名以保持顺序,但面临大Key问题,以及考虑分布式均匀拆分的复杂性。代码示例展示了如何实现定时检查并处理Redis中的键,同时在处理过程中避免阻塞和恢复错误。
摘要由CSDN通过智能技术生成

场景:无实时性要求

其他方案:

  • 使用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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值