建议用方案乙

[toc]

场景

redis 中存在大量 key。 其中有一部分是用户登陆的 session_id, 结构是 :

session_id:1

session_id:2

session_id:3
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

需求: 有多少用户在线

方案

方案甲

keys session_id:*
  • 1.

这种方式简单快捷,一次性查到所有用户。

但是,如果有 1 百万用户,这时候对于 redis 的压力🍐,可想而知。


方案乙

SCAN 方式

记录游标,循环取出

下面是 go 语言代码案例

go1.21

go get github.com/redis/go-redis/v9

redisCli, err := redis.GetRedisCli(c)
	if err != nil || redisCli == nil {
		return resp, errors.New("redis db err")
	}
	
	var cursor uint64 // 记录游标位置,初始为 0
	var keys []string // 查到的所有 key 列表
	iter := 0 // 查询次数
	for {
		batch := int64(1000) // 每批次查询个数
		var keysNew []string // 每批次查到的 key 列表
		keysNew, cursor, err = redisCli.Scan(c, cursor, "session_id:*"), batch).Result()
		if err != nil {
			break
		}
		keys = append(keys, keysNew...) // 追加到全量的数组中
		iter++
		if cursor == 0 { // 当 cursor 等于 0 时,退出循环。第一次和最后一次是 0。
			break
		}
		if iter > 100 { // 避免无限循环
			break
		}
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

拓展

但是有一点要注意,你指定的批次数量,不一定会完全一样,就算库里大于你的单批次的数量。

redis 如何使用 scan, go语言版_Go