面试题答案
一键面试- 思路:
KEYS
命令在生产环境中应谨慎使用,因为它是全量扫描,对性能影响大。但本题要求尽量减少影响,所以可以采用分批次扫描的方式。- 先使用
SCAN
命令迭代获取所有以app:module1:
开头的键,然后对获取到的键进行分析统计不同业务类型的键的数量。
- 实现步骤:
- 使用
SCAN
命令获取键:- 初始化游标为
0
,即cursor = 0
。 - 使用
SCAN
命令,每次迭代获取一定数量(如count = 100
)的键,命令格式为SCAN cursor MATCH app:module1:* COUNT count
。这里MATCH
选项用于筛选出以app:module1:
开头的键,COUNT
选项指定每次迭代返回的键的数量。 - 执行
SCAN
命令后,返回结果是一个数组,第一个元素是新的游标值,若为0
表示迭代结束;第二个元素是本次迭代获取到的键的数组。
- 初始化游标为
- 统计不同业务类型的键的数量:
- 初始化一个字典(在编程语言中,如Python中的
dict
)用于存储不同业务类型的键的数量,例如count_dict = {}
。 - 对每次迭代获取到的键数组进行遍历,以
:
为分隔符分割键,获取业务类型(即分割后的第三个元素)。 - 如果业务类型已经在
count_dict
中,则将其对应的值加1;否则,在count_dict
中添加该业务类型,并将其值设为1。
- 初始化一个字典(在编程语言中,如Python中的
- 循环执行
SCAN
直到结束:- 将每次
SCAN
返回的新游标值赋给cursor
,继续执行SCAN
命令,直到cursor
为0
。
- 将每次
- 最终结果:
- 最终
count_dict
中存储的就是app:module1
下不同业务类型的键的数量。
- 最终
- 使用
例如在Python中实现如下(假设使用redis - py
库):
import redis
r = redis.Redis(host='localhost', port = 6379, db = 0)
cursor = '0'
count_dict = {}
while cursor!= '0':
cursor, keys = r.scan(cursor = cursor, match = 'app:module1:*', count = 100)
for key in keys:
parts = key.decode('utf - 8').split(':')
if len(parts) > 2:
business_type = parts[2]
if business_type in count_dict:
count_dict[business_type] += 1
else:
count_dict[business_type] = 1
print(count_dict)