面试题答案
一键面试实现步骤
- 获取所有动态键:
- 使用
KEYS post:*
命令获取所有以post:
开头的键。不过此命令在生产环境大数据量下不推荐,因为它会阻塞Redis服务器,对于海量数据可考虑使用SCAN
命令。例如:
SCAN 0 MATCH post:* COUNT 1000
- 每次
SCAN
操作返回一个游标和部分匹配的键,通过不断迭代游标来获取所有符合条件的键。
- 使用
- 遍历键获取动态详情:
- 对于获取到的每个键,使用
GET
命令获取对应的值(即动态详情的JSON字符串)。假设获取到的键存储在列表keys_list
中,伪代码如下:
import json import redis r = redis.Redis(host='localhost', port=6379, db = 0) keys_list = [] # 这里假设已经通过SCAN获取到键列表 result = [] for key in keys_list: value = r.get(key) if value: post = json.loads(value) # 这里假设JSON结构中有 'likes' 表示点赞数,'publish_time' 表示发布时间 if 'likes' in post and 'publish_time' in post: if post['likes'] > 100 and is_within_last_week(post['publish_time']): result.append(post) def is_within_last_week(publish_time): # 实现判断发布时间是否在最近一周内的逻辑,这里publish_time假设是时间戳 import time one_week_ago = time.time() - 7 * 24 * 60 * 60 return publish_time > one_week_ago
- 对于获取到的每个键,使用
- 过滤数据:
- 解析获取到的JSON字符串,从中提取点赞数和发布时间字段。
- 检查点赞数是否超过100且发布时间是否在最近一周内,如果满足条件则保留该动态。
性能优化
- 数据结构优化:
- 使用Sorted Set:可以按发布时间创建一个Sorted Set,成员为动态键,分值为发布时间的时间戳。这样可以方便地根据时间范围筛选动态。例如,使用
ZADD
命令添加动态键到Sorted Set中,ZADD post_time_sorted_set <timestamp> <post_key>
。在查询时,通过ZRANGEBYSCORE post_time_sorted_set <start_timestamp> <end_timestamp>
获取最近一周内发布的动态键,再结合GET
命令获取动态详情进行点赞数过滤。 - Hash结构存储动态详情:将动态详情存储为Hash结构,而不是JSON字符串。这样可以直接通过
HGET
命令获取特定字段(如点赞数),避免每次都解析整个JSON字符串。例如,HSET post:1 likes 120 content "This is a post" publish_time 1678932456
。
- 使用Sorted Set:可以按发布时间创建一个Sorted Set,成员为动态键,分值为发布时间的时间戳。这样可以方便地根据时间范围筛选动态。例如,使用
- 缓存与批量操作:
- 缓存常用结果:如果某些动态经常被查询,可以将符合条件的动态缓存到应用层(如Python的字典),减少对Redis的查询次数。
- 批量操作:尽量使用批量操作命令,如
MGET
代替多次GET
。可以将获取到的符合时间范围的键批量获取动态详情,减少网络开销。例如,MGET key1 key2 key3...
。
- 分布式与分片:
- Redis Cluster:在海量数据场景下,使用Redis Cluster进行数据分片。将动态数据分布到多个Redis节点上,提高整体的存储和查询性能。通过一致性哈希算法将键均匀分布到各个节点,当进行查询时,客户端可以根据键计算出对应的节点并直接查询。