MST
星途 面试题库

面试题:缓存设计中复杂业务场景下Redis缓存命中率优化

假设在一个电商系统中,有商品详情页、购物车等功能。商品详情页的数据更新频率较低,购物车数据实时性要求较高。请设计一个Redis缓存方案,以提高缓存命中率,同时保证数据的一致性和系统性能,并阐述在高并发场景下可能遇到的问题及解决方案。
44.6万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

Redis缓存方案设计

  1. 商品详情页缓存
    • 缓存策略:采用LFU(Least Frequently Used,最不经常使用)或LRU(Least Recently Used,最近最少使用)淘汰策略。由于商品详情页数据更新频率低,使用这两种策略能保证长时间不被访问的商品缓存被淘汰,为新的商品缓存腾出空间。
    • 缓存数据结构:使用Hash结构存储商品详情信息,例如以商品ID作为Key,商品详情(如名称、描述、价格、图片等)作为Hash的Field - Value对。这样可以方便地对单个商品的详情进行读写操作。
    • 缓存更新:当商品数据发生变化时,通过消息队列(如Kafka)异步更新Redis中的商品详情缓存。在商品更新逻辑完成后,向消息队列发送更新消息,消费者接收到消息后更新Redis缓存,以减少对业务主流程的影响。
  2. 购物车缓存
    • 缓存策略:采用不淘汰策略,因为购物车数据实时性要求高,要保证购物车数据始终存在于缓存中。
    • 缓存数据结构:使用Hash结构,以用户ID作为Key,购物车中的商品(商品ID - 数量)作为Hash的Field - Value对。这样可以快速定位和更新某个用户的购物车信息。
    • 缓存更新:当用户对购物车进行操作(添加、删除商品,修改商品数量等)时,直接同步更新Redis中的购物车缓存,确保数据的实时性。同时,将购物车操作记录通过消息队列异步持久化到数据库,保证数据的最终一致性。

高并发场景下可能遇到的问题及解决方案

  1. 缓存击穿问题
    • 问题描述:高并发情况下,一个热点商品的缓存过期瞬间,大量请求同时访问数据库,导致数据库压力骤增。
    • 解决方案
      • 互斥锁:在缓存过期时,使用Redis的SETNX(SET if Not eXists)命令获取互斥锁,只有获取到锁的请求才能去查询数据库并更新缓存,其他请求等待。获取锁的请求更新完缓存后释放锁。
      • 永不过期:对于热点商品设置一个超长的过期时间,如一年,同时在数据更新时主动更新缓存,避免因过期导致的击穿问题。
  2. 缓存雪崩问题
    • 问题描述:大量缓存同时过期,导致大量请求直接访问数据库,使数据库不堪重负甚至崩溃。
    • 解决方案
      • 随机过期时间:在设置缓存过期时间时,给每个缓存设置一个随机的过期时间,避免大量缓存同时过期。例如,原本设置1小时过期,可以设置在50 - 70分钟之间随机过期。
      • 二级缓存:采用二级缓存架构,一级缓存使用Redis,二级缓存可以使用本地缓存(如Guava Cache)。当一级缓存失效时,先从二级缓存获取数据,若二级缓存也没有则查询数据库并更新两级缓存,减轻数据库压力。
  3. 缓存一致性问题
    • 问题描述:在高并发读写场景下,可能出现数据库和缓存数据不一致的情况,比如先更新数据库成功,再更新缓存失败。
    • 解决方案
      • 重试机制:当缓存更新失败时,通过重试机制多次尝试更新缓存,直到成功为止。可以设置最大重试次数和重试间隔时间。
      • 异步补偿:将缓存更新失败的记录发送到消息队列,通过消息队列的消费者进行异步补偿操作,确保缓存最终能更新成功。
      • 读写锁:在对数据进行读写操作时,使用读写锁保证同一时间只有一个写操作,读操作可以并发进行,避免读写冲突导致的数据不一致问题。