Redis三大难点之缓存穿透

缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。

解决方案

  1. 缓存空对象,为避免占用资源,一般过期时间会比较短 优点:实现简单,维护方便 缺点:额外的内存消耗,可能造成短期的不一致
  2. 布隆过滤 优点:内存占用较少,没有多余key 缺点:实现复杂,存在误判可能
  3. 增强id的复杂度,避免被猜测id规律
  4. 做好数据的基础格式校验
  5. 加强用户权限校验
  6. 做好热点参数的限流,基于二八原则,我们通常只会缓存常用的那 20% 的热点数据
  7. 设置可访问白名单,用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmaps里面的id进行比较,如果访问id不在bitmaps中,进行拦截,不允许访问
  8. 实时监控,当发现redis的命中率开始急剧降低时,需要及时排查访问对象和和访问数据,和运维人员配合,设置黑名单
Redis三大难点之缓存穿透

设计思想

Redis三大难点之缓存穿透

代码实现

   public ResponseEntity<Object> getUserById(String id) {

        // 从redis中根据key查询用户列表信息
        String user = (String) redisTemplate.opsForValue().get("user:" + id);

        // 如果用户信息不为null、""、"tn",则存在,转化为Issa
        if (StrUtil.isNotBlank(user)) {
            Issa issa = JSONUtil.toBean(user, Issa.class);
            return ResponseEntity.ok(issa);
        }

        if (user != null) {
            return ResponseEntity.status(400).body("没有用户信息");
        }

        // 查询所有用户信息
        Issa userById = userMapper.getUserById(id);

        // 判断是否为空
        if (userById == null) {
            redisTemplate.opsForValue().set("user:" + id, ""10, TimeUnit.SECONDS);
            return ResponseEntity.status(405).body("没有任何一个用户的信息");
        }

        // 转化为字符串
        String issasStr = JSONUtil.toJsonStr(userById);

        // 保存到redis中,并设置超时时间作为兜底方案
        redisTemplate.opsForValue().set(USER_LIST, issasStr, 60, TimeUnit.SECONDS);

        // ok
        return ResponseEntity.ok(userById);
    }


原文始发于微信公众号(步尔斯特):Redis三大难点之缓存穿透

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/47875.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!