面试题答案
一键面试缓存结构设计
- 使用哈希(Hash)结构存储商品信息:
- Redis的哈希结构可以将商品的各个属性作为字段(field),属性值作为值(value)存储。例如,对于商品ID为
123
的商品,使用如下方式存储:
HSET product:123 id 123 HSET product:123 name "示例商品" HSET product:123 price 99.99 HSET product:123 description "这是一个示例商品的描述"
- 优点:这种结构便于对商品的各个属性进行单独的读写操作,同时也能在一次操作中获取商品的所有信息(使用
HGETALL product:123
),减少了网络开销。
- Redis的哈希结构可以将商品的各个属性作为字段(field),属性值作为值(value)存储。例如,对于商品ID为
缓存更新处理
- 实时更新:
- 当商品信息在数据库中发生变化时,立即更新Redis缓存。例如,在商品价格更新的业务逻辑中,先更新数据库中的价格,然后紧接着更新Redis中的价格字段:
# 假设使用Python和Redis-py库 import redis r = redis.Redis(host='localhost', port=6379, db = 0) # 更新数据库价格逻辑 #... # 更新Redis缓存 r.hset('product:123', 'price', new_price)
- 异步更新:
- 可以使用消息队列(如RabbitMQ、Kafka等)。当商品信息变化时,先将更新消息发送到消息队列,然后由一个独立的消费者服务从队列中取出消息并更新Redis缓存。这种方式可以减少主业务逻辑的延迟,提高系统的整体响应速度。
缓存穿透处理
- 布隆过滤器(Bloom Filter):
- 在查询商品时,先通过布隆过滤器判断商品ID是否存在。布隆过滤器可以使用Redis的
BF.ADD
和BF.EXISTS
命令。在商品入库时,将商品ID添加到布隆过滤器中:
BF.ADD product_ids_bloom_filter 123
- 当查询商品时:
if not r.execute_command('BF.EXISTS', 'product_ids_bloom_filter', product_id): return "商品不存在"
- 优点:布隆过滤器可以在空间效率很高的情况下,快速判断一个元素是否在集合中,极大减少了对Redis和数据库的无效查询。但要注意布隆过滤器存在误判率,不过可以通过合理设置参数来降低误判率。
- 在查询商品时,先通过布隆过滤器判断商品ID是否存在。布隆过滤器可以使用Redis的
- 空值缓存:
- 当查询一个不存在的商品ID时,在Redis中设置一个空值缓存(例如
SET product:不存在的ID null EX 60
,设置60秒过期)。这样下次查询同样的不存在的ID时,直接从Redis获取空值,避免查询数据库。但要注意空值缓存的过期时间设置,过长可能导致新商品上架后,短时间内无法查询到。
- 当查询一个不存在的商品ID时,在Redis中设置一个空值缓存(例如