【Redis】什么是缓存穿透 ? 怎么解决

缓存穿透(Cache Penetration)是指查询的数据在缓存和数据库中都不存在,导致每次请求都会穿透缓存直接访问数据库,进而使缓存失去保护数据库的作用。频繁的缓存穿透可能会导致数据库的压力过大,甚至崩溃。

解决缓存穿透的方法

  1. 缓存空结果

    • 当查询结果为空时,也将这个结果缓存起来,并设置一个较短的过期时间,防止短时间内频繁查询相同的无效数据。
    java 复制代码
    import redis.clients.jedis.Jedis;
    
    public class CachePenetrationExample {
        public static void main(String[] args) {
            Jedis jedis = new Jedis("localhost");
    
            String key = "nonexistent_key";
            String value = jedis.get(key);
    
            if (value == null) {
                // 从数据库查询数据(假设为null)
                value = getFromDatabase(key);
    
                if (value == null) {
                    // 缓存空结果,设置过期时间为5分钟
                    jedis.setex(key, 300, "");
                } else {
                    // 缓存实际结果
                    jedis.set(key, value);
                }
            }
    
            // 关闭连接
            jedis.close();
        }
    
        private static String getFromDatabase(String key) {
            // 模拟数据库查询
            return null;
        }
    }
  2. 布隆过滤器(Bloom Filter)

    • 在访问缓存之前,使用布隆过滤器快速判断数据是否存在于数据库中,减少不必要的数据库查询。
    java 复制代码
    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    
    public class BloomFilterExample {
        private static BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(), 1000000);
    
        public static void main(String[] args) {
            // 初始化布隆过滤器(假设已加载所有可能的键)
            bloomFilter.put("existing_key");
    
            String key = "nonexistent_key";
    
            if (!bloomFilter.mightContain(key)) {
                System.out.println("Key " + key + " is not likely in the database.");
            } else {
                // 继续缓存和数据库查询流程
                // ...
            }
        }
    }
  3. 参数校验和限制

    • 对传入的参数进行校验,过滤掉不合法的请求,避免恶意攻击导致的缓存穿透。
    java 复制代码
    public class InputValidationExample {
        public static void main(String[] args) {
            String key = "invalid_key";
    
            if (isValidKey(key)) {
                // 继续缓存和数据库查询流程
                // ...
            } else {
                System.out.println("Invalid key: " + key);
            }
        }
    
        private static boolean isValidKey(String key) {
            // 简单的合法性校验逻辑(根据业务需求定制)
            return key != null && key.matches("^[a-zA-Z0-9_]+$");
        }
    }

总结

缓存穿透的问题可以通过多种方式解决,包括缓存空结果、使用布隆过滤器和参数校验等。这些方法可以有效地减少对数据库的无效查询,保护数据库的稳定性。结合具体业务场景,选择适合的方法来预防和解决缓存穿透问题。

相关推荐
呆萌很2 小时前
数据库逻辑结构设计
数据库
howdoyoudo2026062 小时前
当新案例冲击旧框架:分类系统的宿命与修正路径
大数据·网络·数据库·人工智能·安全·ai·分类
自己的九又四分之三站台2 小时前
GeoPackage 到底适合什么场景:从 SQLite 容器到空间数据格式选型
数据库·oracle·sqlite
东方护航数据恢复(深圳)3 小时前
勒索病毒加密数据库怎么办?深圳 0 赎金解密恢复实录【东方护航数据恢复深圳店】
数据库·数据恢复·服务器数据恢复·勒索病毒·数据镜像
倔强的石头_3 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
数据库
苦瓜打怪兽3 小时前
PostgreSQL 报错“字段 datlastsysoid 不存在”排查与解决
数据库·postgresql
XLYcmy3 小时前
PDF 论文处理器 — 技术报告文档
数据库·python·网络安全·pdf·embedding·dify·rag
ShineWinsu3 小时前
对于Redis:RDB持久化的解析
linux·数据库·redis·缓存·面试·持久化·rdb
做运维的阿瑞3 小时前
MYSQL从语义到执行计划:UNION、EXISTS、IN 的深度辨析
数据库·sql·mysql
Elastic 中国社区官方博客13 小时前
将你自己的密钥用于现有 Elastic Cloud 部署
大数据·数据库·elasticsearch·全文检索