MST

星途 面试题库

面试题:缓存设计的多维度数据模型及命中率提升

在一个社交网络应用中,存在多种类型的数据,如用户资料、好友关系、动态信息等,每种数据的访问模式和更新频率差异很大。请设计一套基于多维度数据模型的缓存方案,以最大化缓存命中率,并分析如何在高并发、数据一致性要求高的场景下保证缓存系统的高效稳定运行,包括但不限于缓存淘汰算法的选择、缓存穿透和雪崩问题的解决策略。
24.7万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

基于多维度数据模型的缓存方案设计

  1. 按数据类型和访问模式分区缓存
    • 用户资料:通常访问频率高且相对稳定,适合采用分布式缓存(如 Redis)。可以以用户 ID 为 key,将整个用户资料对象作为 value 进行缓存。考虑到可能有部分用户资料更新较为频繁(如头像、签名等),可以将这部分单独拆分缓存,设置较短的过期时间。
    • 好友关系:访问模式可能是根据用户 ID 获取其好友列表。可以使用 Redis 的 Set 数据结构,以用户 ID 为 key,好友 ID 集合为 value 进行缓存。由于好友关系变动相对不频繁,缓存过期时间可设置较长。
    • 动态信息:动态信息更新频率高且访问量大。可以按时间线维度进行缓存,例如,以用户 ID 和时间范围(如一天)为复合 key,缓存该用户在特定时间范围内发布的动态列表。同时,对于热门动态,可以额外设置全局缓存,以提高访问效率。
  2. 多级缓存架构
    • 一级缓存:采用本地缓存(如 Guava Cache),部署在应用服务器本地。它的优点是访问速度极快,适合缓存近期频繁访问的数据。由于本地缓存容量有限,设置较小的缓存空间和较短的过期时间。
    • 二级缓存:使用分布式缓存(如 Redis)作为二级缓存。它具有更大的存储容量和分布式特性,能应对大规模数据的缓存需求。一级缓存未命中时,才访问二级缓存。

高并发和数据一致性场景下的缓存系统优化

  1. 缓存淘汰算法的选择
    • LRU(最近最少使用):适用于大部分数据的缓存淘汰。它基于访问时间来判断数据的活跃程度,将最近最少使用的数据淘汰。在 Redis 中,可以通过配置 maxmemory-policy volatile - lru 来启用针对设置了过期时间的 key 的 LRU 淘汰策略,或 maxmemory-policy allkeys - lru 对所有 key 启用 LRU 淘汰策略。
    • LFU(最不经常使用):对于一些长期访问频率较低但偶尔会被大量访问的数据,LFU 更为合适。它根据数据的访问频率来淘汰,Redis 4.0 后也提供了近似 LFU 策略(maxmemory - policy volatile - lfumaxmemory - policy allkeys - lfu)。
  2. 缓存穿透问题的解决策略
    • 布隆过滤器:在查询数据前,先通过布隆过滤器判断数据是否存在。如果布隆过滤器判断不存在,则直接返回,避免查询数据库。布隆过滤器可以使用 Redis 的 BitMap 来实现,将所有可能存在的 key 提前通过哈希函数映射到 BitMap 中。
    • 缓存空值:当查询数据库未命中时,将空值也缓存起来,并设置较短的过期时间。这样下次查询相同 key 时,直接从缓存获取空值,避免重复查询数据库。
  3. 缓存雪崩问题的解决策略
    • 设置随机过期时间:避免大量 key 在同一时间过期。在设置缓存过期时间时,在一个基础时间上加上一个随机的时间偏移,使得 key 的过期时间分散。
    • 分级缓存:如上述的多级缓存架构,一级缓存可以在二级缓存大量失效时起到一定的缓冲作用,减少对数据库的直接冲击。
    • 互斥锁:在缓存失效时,使用互斥锁(如 Redis 的 SETNX 命令)保证只有一个线程去查询数据库并更新缓存,其他线程等待。这样可以避免大量线程同时查询数据库导致的性能问题。