redis高级篇2 springboot+redis+bloomfilter实现过滤案例

news2024/9/24 5:30:25

一 bloomfilter的作用

1.1 作用

Bloomfilter:默认是有0组成bit数组和hash函数构成的数据结构,用来判断在海量数据中是否存在某个元素。

应用案例:解决缓存穿透。Bloomfilter放在redis前面,如果查询bf中没有则直接返回,如果存在则查询redis,如果redis不存在,则查询mysql数据库。bf拦截一些不必要的请求。

1.2 案例

1.2.1 流程逻辑

1.构建过程

1)预加载符合条件的记录;2)计算每条记录的hash值;3)计算hash值对应bitmap数组的位置;4)修改值为1;

2.查询过程

1)计算元素的hash位置;2)计算hash值对应二进制数组的位置;3)找到数组中对应位置的值,0代表不存在;1代表存在。

1.2.2 setbit的构建过程

1.@postConstruct初始化白名单数据

2.计算元素的hash值

3.通过上一步的hash值算出对应的二进制数组的坑位,将对应坑位的值修改为数字;1表示存在。

1.2.3 查询是否存在

1.计算元素的hash值;2通过上一步的hash值计算出对应的二进制数组对应的坑位,返回对应坑位的值,0表示无;1表示存在。

二 工程搭建

2.1 工程结构

2.2 不使用bloomfilter过滤器的情况 

2.2.1 新增初始化数据

1.controller

2.service

 2.2.2 查询数据

1.controller

 2.service

 2.2.3 初始化数据库

1.数据库配置

2.数据库脚本

CREATE TABLE `t_customer` (
  `id` bigint(11) NOT NULL,
  `cname` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  `birth` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 2.2.4 启动服务测试

1.页面访问新增数据

http://localhost:8083/customer/add

2.访问查询接口

访问存在的数据id=1

访问不存在的数据id=3

 控制台显示信息:

2023-07-31 18:44:11.850  INFO 4172 --- [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
刚开始redis不存在。。。。。。

 3.查看数据库接口

4.查看redis

 2.3 使用bloomfilter过滤器的情况 

2.3.1 逻辑架构

2.3.2 初始化白名单数据

这里将customer:12作为key,存储到redis数据库中。

@Component
@Slf4j
public class BloomFilterInit
{
    @Resource
    private RedisTemplate redisTemplate;

    @PostConstruct //初始化白名单数据
    public void initWhiteListData(){
        //1.白名单客户加载到布隆过滤器中
        String key="customer:12";
        //2.计算hashvalues,由于存储计算出来可能存在负数,我们取绝对值
        int hashValue=Math.abs(key.hashCode());
        //3.通过hashvalue和2的32次方后取余,获得对应的下标坑位
        long index=(long)(hashValue%Math.pow(2,32));
        log.info("key"+"对应的index:"+index);
        //4.设置redis里面的bitmap对应的白名单 whitelistcustomer的坑位,将改值设置为1;
        redisTemplate.opsForValue().setBit("whiteListCustomer",index,true);
    }
}

截图

 2.3.3 使用bloomfilter过滤判断

 public Customer findDataByBloomFilter(Integer id){
        //1.封装key
        String key=CACHA_KEY_CUSTOMER+id;
        //2.布隆过滤器check,无是绝对无,有是可能有
        //===============================================
        if(!checkUtils.checkWithBloomFilter("whiteListCustomer",key))
        {
            log.info("白名单无此顾客,不可以访问: "+key);
            return null;
        }
       //3.查询redis
        Customer customer=(Customer) redisTemplate.opsForValue().get(key);
        if(customer==null){
            System.out.println("redis不存在。。。。。。");
            //4.redis为空,查询mysql
            customer=customerDao.selectByPrimaryKey(id);
            if(customer!=null){
                System.out.println("redis不存在,查询mysql存在");
                //5.mysql中数据存在, 把mysq查询出来的数据回写redis,保持一致性
                redisTemplate.opsForValue().set(key,customer);
                System.out.println("redis不存在,查询mysql存在,回写redis最新数据....");
            }
        }
        return customer;

    }

checkutil工具类:

package com.ljf.redis.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @auther zzyy
 * @create 2022-12-27 14:56
 */
@Component
@Slf4j
public class CheckUtils
{
    @Resource
    private RedisTemplate redisTemplate;

    public boolean checkWithBloomFilter(String checkItem,String key)
    {
        int hashValue = Math.abs(key.hashCode());
        long index = (long)(hashValue % Math.pow(2,32));
        boolean existOK = redisTemplate.opsForValue().getBit(checkItem,index);
        log.info("--->key:"+key+" 对应坑位下标index: "+index+" 是否存在:"+existOK);

        return existOK;
    }
}

2.截图

  2.3.4 判断测试

1.访问customer:1 但是初始白名单放入的是customer:12; 不存在则一定过滤掉。

控制台:

2023-07-31 18:47:43.243  INFO 4172 --- [io-8083-exec-10] com.ljf.redis.util.CheckUtils            : --->key:customer:1 对应坑位下标index: 1581185131 是否存在:false
2023-07-31 18:47:43.243  INFO 4172 --- [io-8083-exec-10] c.l.r.service.impl.CustomerServiceImpl   : 白名单无此顾客,不可以访问: customer:1

2.修改初始化白名单,customer:12 改为customer:1

3.再次启动服务,再次访问

4.控制台信息

 2023-07-31 19:10:08.794  INFO 19236 --- [nio-8083-exec-2] com.ljf.redis.util.CheckUtils            : --->key:customer:1 对应坑位下标index: 1581185131 是否存在:true

5.redis中查看

127.0.0.1:6379> get whiteListCustomer
@
127.0.0.1:6379> 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

opencv中轮廓相关属性

一、介绍 findContours() :The function retrieves contours from the binary image。 二、代码 void main() {Mat src imread("match00.bmp", IMREAD_GRAYSCALE);Mat mask;threshold(src, mask, 128, 255, cv::THRESH_BINARY_INV);Mat element cv::g…

tcl学习之路(一)(Vivado与Tcl)

学习第一步:安装tcl编译软件 点击这里进入activestate的官网,下载你喜欢的操作系统所需的安装包。这里我下载的是windows下的安装包。一步一步安装即可。   那么,安装后,我们可以在开始的菜单栏处看到三个应用程序。      …

Python爬取微博相册, 批量下载

xpath插件解析到所有图片的url地址 xpath下载地址: https://www.crxsoso.com/webstore/detail/hgimnogjllphhhkhlmebbmlgjoejdpjl 快捷键: CtrlShiftX 不会xpath语法可以看这里: https://www.w3school.com.cn/xpath/xpath_syntax.asp //div[class"woo-box-item-inlineBl…

P1090 [NOIP2004 提高组] 合并果子

题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出&#xff0…

图解TCP 三次握手和四次挥手的高频面试题(2023最新版)

大家好,最近重新整理了一版 TCP 三次握手和四次挥手的面试题(2023最新版)。 ----- 任 TCP 虐我千百遍,我仍待 TCP 如初恋。 巨巨巨巨长的提纲,发车!发车! img TCP 基本认识 TCP 头格式有哪些…

[VRTK4.0]获取指针,并提供有效无效位置

学习目标: 演示如何将场景中的游戏对象设置为弯曲指针的无效目标。 流程: 紧接上篇,我们已经创建了一个曲线,并且使用 OpenXR 指针姿势来确保指针方向始终与 OpenXR 控制器的正确方向匹配。 接下来我们要实现如何将场景中的游戏对…

web-6-深入理解JSP:探索其核心概念和特性

JSP 今日目标: 理解 JSP 及 JSP 原理 能在 JSP中使用 EL表达式 和 JSTL标签 1,JSP 概述 JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的网页技术,其中既可以定义 HTML、JS、CSS…

计算机视觉:卷积层的参数量是多少?

本文重点 卷积核的参数量是卷积神经网络中一个重要的概念,它决定了网络的复杂度和计算量。在深度学习中,卷积操作是一种常用的操作,用于提取图像、语音等数据中的特征。卷积神经网络的优势点在于稀疏连接和权值共享,这使得卷积核的参数相较于传统的神经网络要少很多。 举例…

leetcode每日一题Day2——344. 反转字符串

✨博主:命运之光 🦄专栏:算法修炼之练气篇(C\C版) 🍓专栏:算法修炼之筑基篇(C\C版) 🐳专栏:算法修炼之练气篇(Python版) …

WEB:mfw

背景知识 Git泄露 Githack使用 命令执行漏洞 题目 这里页面里有Git,猜测是Git泄露 先用dirsearch扫一下 确实存在.git目录,可以尝试访问一下 使用Githack来下载并恢复.git文件 这里记得使用的时候关闭杀毒软件 结果会自动保存 点进去先看一下flag这个…

Flyway——修改表名称与序列名称

文章目录 前言脚本修改表名称修改序列 前言 开发中一次偶然的机会,Oracle 12c 更换为 11g ,需要对表名称的长度和序列长度做限制要求。 11g相对12c而言,表名称与序列名称的长度,不能超过30个字符。 在开发中做了更改,…

fixed-视频倍速

首先fn12打开开发者模式 然后进入console控制台 document.getElementsByTagName(“video”)[0].playbackRate 3 数字3 就是多少倍速 可以替换想要的倍速 直接快进到 最后 let video document.getElementsByTagName(‘video’) for (let i0; i<video.length; i) { video[…

Linux虚拟机安装tomcat(图文详解)

目录 第一章、xshell工具和xftp的使用1.1&#xff09;xshell下载与安装1.2&#xff09;xshell连接1.3&#xff09;xftp下载安装和连接 第二章、安装tomcat1.1&#xff09;关闭防火墙&#xff0c;传输tomcat压缩包到Linux虚拟机12&#xff09;启动tomcat 第一章、xshell工具和xf…

韦东山Linux驱动入门实验班(5)LED驱动---驱动分层和分离,平台总线模型

前言 &#xff08;1&#xff09;前面已经已经详细介绍了LED驱动如何进行编写的代码。如果韦东山Linux驱动入门实验班&#xff08;4&#xff09;LED驱动已经看懂了&#xff0c;驱动入门实验班后面的那些模块实验&#xff0c;其实和单片机操作差不太多了。我就不再浪费时间进行讲…

Netty各组件基本用法、入站和出站详情、群聊系统的实现、粘包和拆包

Netty Bootstrap和ServerBootstrapFuture和ChannelFutureChannelSelectorNioEventLoop和NioEventLoopGroupByteBuf示例代码 Channel相关组件入站详情出站详情对象编解码ProtoBuf和ProtoStuffnetty实现群聊系统粘包和拆包TCP协议特点举个例子 Bootstrap和ServerBootstrap Boots…

【管理设计篇】聊聊分布式配置中心

为什么需要配置中心 对于一个软件系统来说&#xff0c;除了数据、代码&#xff0c;还有就是软件配置&#xff0c;比如操作系统、数据库配置、服务配置 端口 ip 、邮箱配置、中间件软件配置、启动参数配置等。如果说是一个小型项目的话&#xff0c;可以使用Spring Boot yml文件…

Nginx解决文件服务器文件名显示不全的问题

Nginx可以搭建Http文件服务器&#xff0c;但默认的搭建会长文件名显示不全&#xff0c;比如如下&#xff1a; 问题&#xff1a;显示不全&#xff0c;出现...&#xff0c;需要进行解决 这里使用重新编绎nginx的方式&#xff0c;见此文&#xff1a; https://unix.stackexchange…

CS5265国产Typec转HDMI音视频转换芯片可替代RTD2172

集睿致远/ASL推出的CS5265是一款高性能Type-C/DP1.4至HDMI2.0b转换器IC&#xff0c;设计用于将USB type c源或DP1.4源连接至HDMI2.0b接收器。CS5265集成了DP1.4兼容接收机和HDMI2.0b兼容发射机。此外&#xff0c;CC控制器还用于CC通信&#xff0c;以实现DP Alt模式。DP接口包括…

ARM 常见汇编指令学习 9 - 缓存管理指令 DC 与 IC

文章目录 ARM64 DC 与 IC 指令 上篇文章&#xff1a;ARM 常见汇编指令学习 8 - dsb sy 指令及 dsb 参数介绍 ARM64 DC 与 IC 指令 AArch64指令集中有两条关于缓存维护&#xff08;cache maintenance&#xff09;的指令&#xff0c;分别是IC和DC。 IC 是用于指令缓存操作&…

设备管理升级:揭秘设备健康管理的核心优势

随着工业企业迎来数字化转型的浪潮&#xff0c;设备管理在实现升级和卓越运营方面扮演着关键角色。传统的设备管理方式已经难以适应复杂多变的生产环境&#xff0c;因此设备健康管理作为数字化转型的核心优势应运而生。本文将深入探讨设备健康管理的核心优势&#xff0c;以揭示…