51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在高并发交易系统中,如何优化缓存以应对缓存雪崩、缓存穿透、缓存击穿问题?请举例说明具体优化策略(如预加载、布隆过滤器、热点数据预热)。

三菱日联银行Global Markets难度:困难

答案

1) 【一句话结论】:高并发交易系统中,应对缓存雪崩、穿透、击穿需通过**预加载(预热)、布隆过滤器(防穿透)、热点数据预热(防击穿)**等组合策略,结合分布式锁、限流、多级缓存,分场景针对性优化,避免单一策略失效。

2) 【原理/概念讲解】:

  • 缓存雪崩:指缓存中大量数据因统一过期时间同时失效,导致大量请求直接冲击数据库,引发系统崩溃。成因:缓存统一过期时间、系统维护或重启。类比:雪球越滚越大,初始小问题引发连锁反应。
  • 缓存穿透:指无效查询(如空key或数据库不存在的数据)持续请求,导致缓存和数据库都无结果,造成数据库压力。成因:恶意攻击、无效查询逻辑。类比:空投炸弹,目标不存在,却持续投掷。
  • 缓存击穿:指缓存中热点数据(高频访问)突然失效,大量请求直接到数据库,导致数据库压力激增。成因:热点key过期、并发写入导致失效。类比:热门商品突然断货,大量顾客涌向商店。

3) 【对比与适用场景】:

问题类型定义典型成因典型场景优化策略
缓存雪崩大量缓存失效,请求直连数据库统一过期时间、系统重启系统维护时预热、分布式锁、限流、多级缓存
缓存穿透无效key导致缓存/数据库无结果恶意攻击、无效查询查询不存在的数据布隆过滤器、缓存空值、热点预热
缓存击穿热点key失效,请求直连数据库热点key过期、并发写入热门数据访问预热、分布式锁、多级缓存

4) 【示例】(以用户登录和股票数据为例):

  • 缓存雪崩(预加载):用户登录时,将用户信息(如用户ID、账户余额)提前加载到Redis缓存,设置较长的过期时间(如1小时),避免后续请求失效。代码伪代码:
    def load_hot_data():
        users = db.query_all_users()  # 从数据库加载所有用户
        for user in users:
            cache.set(f"user:{user.id}", user, timeout=3600)  # 预热用户数据
    
  • 缓存穿透(布隆过滤器):查询用户时,先检查布隆过滤器(如Redis的布隆过滤器实现),若为false则直接返回“用户不存在”,避免数据库查询。代码伪代码:
    def query_user_by_id(user_id):
        if bf.contains(f"user:{user_id}"):  # 检查布隆过滤器
            data = cache.get(f"user:{user_id}")
            if data: return data
            else: return None  # 缓存空值
        else: return "用户不存在"  # 误判为false
    
  • 缓存击穿(热点数据预热):热门股票数据(如A股指数)提前加载到缓存,设置短失效时间(如5分钟),并使用分布式锁保证并发写入时不会重复加载。代码伪代码:
    def get_stock_price(stock_id):
        key = f"stock:{stock_id}"
        with distributed_lock(key):  # 分布式锁
            if not cache.exists(key):
                price = db.get_stock_price(stock_id)  # 从数据库获取
                cache.set(key, price, timeout=300)  # 热点数据预热
            return cache.get(key)
    

5) 【面试口播版答案】:
面试官您好,针对高并发交易系统中的缓存问题,核心是通过组合策略应对雪崩、穿透、击穿。
首先,缓存雪崩是缓存统一过期导致大量请求直连数据库,解决用预加载(系统启动时加载热点数据,如用户信息、热门股票),结合分布式锁控制并发写入,避免重复加载;同时限流防雪崩扩散。比如用户登录后,将用户数据提前存入缓存,后续请求直接从缓存获取,减少数据库压力。
其次,缓存穿透是无效key(如不存在的用户ID)导致数据库压力,用布隆过滤器,先检查缓存是否存在该key,若为false则直接返回“不存在”,避免数据库查询。比如查询用户时,先通过布隆过滤器判断,若为false则跳过数据库。
最后,缓存击穿是热点key(如热门股票)失效,用热点数据预热,提前加载到缓存,设置短失效时间(如5分钟),并加分布式锁保证并发写入时不会重复加载。比如股票数据更新时,用锁控制并发,避免重复查询数据库。
总结来说,通过预加载、布隆过滤器、热点预热结合缓存策略,可有效应对高并发下的缓存问题。

6) 【追问清单】:

  • 追问1:预加载如何处理并发写入?
    回答要点:用分布式锁(如Redis的SETNX)控制并发,避免重复加载;或者设置乐观锁,检查缓存是否已存在再写入。
  • 追问2:布隆过滤器的误判率如何控制?
    回答要点:布隆过滤器有误判率(如1%),可通过调整位数组大小降低误判率,或结合缓存空值(若布隆过滤器为false,再查数据库,若为空则返回缓存空值)。
  • 追问3:多级缓存(如Redis+Memcached)如何优化?
    回答要点:Memcached作为热点缓存,Redis作为持久化缓存,通过缓存穿透时先查Memcached,若为空再查Redis,最后查数据库,减少数据库压力。
  • 追问4:分布式锁的选择?
    回答要点:用Redis的SETNX实现分布式锁,或ZooKeeper,需考虑锁的超时机制,避免死锁。
  • 追问5:缓存失效后如何回源?
    回答要点:设置缓存穿透时,若数据库无结果,将空值存入缓存(如TTL设为1秒),避免后续请求重复查询数据库。

7) 【常见坑/雷区】:

  • 坑1:单一策略:只说一种方法(如只提预加载),忽略组合策略,面试官会认为理解不全面。
  • 坑2:预加载的内存压力:没考虑系统冷启动时的内存占用,可能导致OOM(内存溢出)。
  • 坑3:布隆过滤器误判率:没说明误判率的影响,或没提如何降低误判率。
  • 坑4:缓存击穿时没提分布式锁:只说预热,没考虑并发写入时的冲突。
  • 坑5:缓存雪崩的限流:没提限流策略,导致雪崩扩散。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1