【线上故障排查】缓存穿透攻击的识别与布隆过滤器(面试题 + 3 步追问应对 + 案例分析)

一、高频面试题

问题1:什么是缓存穿透?它对系统的核心危害是什么?
参考答案:缓存穿透指的是用户请求的数据在缓存和数据库中都不存在,导致请求直接绕过缓存打到数据库。核心危害是大量无效请求会耗尽数据库资源,比如CPU、内存或连接数,严重时可能引发数据库宕机,进而导致整个系统崩溃,影响服务可用性。

  • 第一步追问:缓存穿透和缓存雪崩有什么本质区别?
    参考答案:两者本质不同。缓存穿透是请求不存在的数据,攻击或逻辑漏洞导致“无中生有”;缓存雪崩是大量缓存同时失效,请求集中打到数据库,属于“有中生无”。前者是恶意或异常请求问题,后者是缓存架构设计问题。

  • 第二步追问:怎么从系统日志中识别缓存穿透?
    参考答案:可以观察日志中是否有大量相同或规律性的不存在的key请求,比如频繁出现“数据库查询结果为空”的记录,且请求量远超正常业务场景。同时,这类请求的响应时间可能较短(因为直接查库返回空),但数据库连接数或QPS会异常升高。

  • 第三步追问:如果业务中偶尔出现正常的空数据请求,需要处理吗?为什么?
    参考答案:需要区分处理。偶尔的正常空请求(比如用户查询已删除的订单)无需特殊处理,但如果短时间内大量出现,可能是缓存穿透的前兆。这时候可以通过统计请求频率、分析key分布规律来判断是否需要介入,比如设置请求频率阈值触发预警。

问题2:布隆过滤器如何解决缓存穿透?它的核心原理是什么?
参考答案:布隆过滤器通过“预存存在的key”来拦截无效请求。核心原理是用多个哈希函数将数据库中存在的key映射到位数组(比特数组)的不同位置,标记为1。当新请求到来时,用同样的哈希函数计算key对应的位,若所有位都是1,则认为key可能存在(进入数据库查询);只要有一个位是0,就直接判定key不存在,拦截请求。

  • 第一步追问:布隆过滤器为什么会存在误判?误判类型是“漏判”还是“误判存在”?
    参考答案:因为哈希函数的“哈希碰撞”问题,不同key可能映射到相同的位,导致不存在的key被误判为存在(假阳性)。但它不会漏判——若布隆过滤器判定不存在,数据一定不存在(因为只要有一个哈希函数对应的位是0,就说明没被存入过)。

  • 第二步追问:如何降低布隆过滤器的误判率?实际应用中需要权衡什么?
    参考答案:可以增加位数组的大小(比如扩大到数据量的10倍以上)或调整哈希函数的数量(通常为(m/n)ln2,m是位数组长度,n是元素数)。但这会增加内存占用和计算成本,需要在误判率、内存空间和性能之间做权衡。比如金融场景可能要求更低误判率,而普通业务可接受稍高误判率来节省资源。

  • 第三步追问:布隆过滤器的数据会永久存储吗?如果数据库数据更新了,如何处理?
    参考答案:布隆过滤器不建议永久存储,因为它不支持删除操作(删除一个key可能影响其他key的映射位)。如果数据库数据新增,需要定期或实时将新key同步到布隆过滤器;如果数据删除,无法直接从布隆过滤器中移除,只能重建整个布隆过滤器(比如基于数据库全量数据重新生成),或者采用“可删除的布隆过滤器”变种(如Counting Bloom Filter,但会增加内存消耗)。

二、案例分析

1、故障现象

1.1 线上告警突发

某电商平台在日常运营中,监控系统突然发出数据库告警:MySQL集群QPS(每秒查询率)从正常的2000飙升至15000,CPU使用率突破90%,慢查询日志激增。与此同时,Redis缓存命中率从95%骤降至60%,大量请求直接穿透缓存访问数据库。

1.2 用户体验恶化

用户端反馈商品详情页加载缓慢,部分页面甚至出现504 Gateway Timeout错误。订单提交成功率从99.9%下降至95%,支付系统也开始出现超时告警。通过APM工具分析,发现数据库查询平均耗时从80ms增加到500ms。

1.3 异常请求特征

运维团队进一步分析访问日志,发现大量针对不存在商品ID的查询请求,例如:

/product/999999999
/product/1000000000
/product/1000000001

这些请求频率极高,每秒超过500次,且请求IP地址分散,初步怀疑遭受缓存穿透攻击。

2、故障分析

2.1 缓存穿透原理

当请求查询一个不存在于缓存中的数据时,请求会直接访问数据库。如果攻击者恶意构造大量不存在的KEY进行请求,这些请求会穿透缓存,全部压到数据库上,导致数据库负载激增。

2.2 攻击路径分析

通过流量镜像工具分析,发现攻击请求具有以下特征:

  1. 规律性请求:请求的商品ID呈等差数列递增,步长为1
  2. 高频次访问:单个IP每秒发送超过100个请求
  3. 全量穿透:所有请求的商品ID均不存在于缓存中
2.3 潜在风险评估
  • 数据库崩溃:持续的高负载可能导致数据库服务器宕机
  • 雪崩效应:数据库响应缓慢可能引发其他服务级联故障
  • 数据泄露风险:攻击者可能通过错误信息获取数据库结构

3、故障定位

3.1 缓存层诊断

使用Redis监控命令分析缓存访问情况:

# 查看缓存命中率
redis-cli info stats | grep hit_rate
# 查看热门KEY
redis-cli --hotkeys
# 分析KEY分布
redis-cli keys "product:*" | wc -l

发现缓存中确实不存在攻击请求的商品ID,且这些KEY的访问频率异常高。

3.2 应用层分析

在应用服务器上部署Arthas进行动态诊断,使用trace命令追踪缓存查询逻辑:

// 商品查询服务关键代码
public Product getProduct(Long productId) {
   
    // 从Redis获取商品信息
    String key = "product:" + productId;
    String json = redisTemplate.opsForValue().get(key);
    
    if (json != null) {
   
        return JSON.parseObject(json, Product.class);
    }
    
    // 缓存未命中,查询数据库
    Product product = productDao.selectById(productId);
    
    if (product 

你可能感兴趣的:(从项目到面试:Java,高频面试题场景化通关指南,缓存,java,后端,spring,boot,linux,redis)