redis穿透解决方案

2024-06-18 12:30
文章标签 redis 穿透 解决方案

本文主要是介绍redis穿透解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Redis缓存穿透是指查询一个不存在于数据库中的数据(通常是恶意用户发起的连续请求),由于缓存中没有,每次请求都会穿透到数据库,这可能会对数据库造成不必要的压力。解决缓存穿透问题的常见策略包括:
       1.  布隆过滤器:用于判断一个元素是否可能存在于集合中,即使它返回存在,也可能是个假阳性(误报),但不会出现假阴性(即如果布隆过滤器说不存在,则该元素一定不存在)。因此,可以在查询数据库之前先检查布隆过滤器。

       2.  空值缓存:即使数据库中没有找到对应记录,也将空值(如null)写入缓存,并设置一个较短的有效期。这样,后续相同请求在缓存有效期内可以直接从缓存中得到结果,而不需要再次访问数据库。

       3. 设置黑白名单:通过白名单使需要的请求访问,通过黑名单防止攻击。

首先,确保你的项目中包含了Spring Data Redis和Guava的依赖。

布隆过滤器配置

import com.google.common.hash.Funnel;
import com.google.common.hash.Hashing;
import com.google.common.math.LongMath;
import com.google.common.primitives.Chars;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 布隆过滤器配置类,用于初始化布隆过滤器的实例及其相关组件。*/
@Configuration
public class BloomFilterConfig {/*** 创建字符串处理的Funnel,用于将字符串转换为哈希输入。* * @return 字符串Funnel实例*/@Beanpublic Funnel<String> stringFunnel() {return (from, into) -> Chars.forEachUtf8(from, c -> into.putChar(c));}/*** 初始化布隆过滤器,基于预期插入数量和误报率进行配置。* * @param funnel 字符串处理的Funnel* @return 布隆过滤器实例*/@Beanpublic BloomFilter<String> bloomFilter(Funnel<String> funnel) {int expectedInsertions = 100000; // 预计需要插入过滤器的元素数量double fpp = 0.01; // 可接受的误报率,即预测为存在但实际上不存在的概率// 计算所需的哈希函数数量int numHashFunctions = LongMath.log2(LongMath.pow(2, Long.SIZE) / expectedInsertions * fpp);// 创建布隆过滤器实例return BloomFilter.create(funnel, expectedInsertions, fpp, Hashing.murmur3_128());}
}

缓存服务实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;/*** 缓存服务实现类,负责处理数据的缓存逻辑,包括使用布隆过滤器和空值缓存策略防止缓存穿透。*/
@Service
public class CacheService {private final StringRedisTemplate redisTemplate;private final BloomFilter<String> bloomFilter;/*** 构造函数注入Redis模板和布隆过滤器实例。** @param redisTemplate Redis操作模板* @param bloomFilter 布隆过滤器实例*/@Autowiredpublic CacheService(StringRedisTemplate redisTemplate, BloomFilter<String> bloomFilter) {this.redisTemplate = redisTemplate;this.bloomFilter = bloomFilter;}/*** 获取数据的方法,首先检查布隆过滤器,然后尝试从Redis缓存中获取,* 若缓存未命中且布隆过滤器认为可能存在,则查询数据库,并实施空值缓存策略。** @param key 数据的唯一标识* @return 查询到的数据或空值、提示信息*/public String getData(String key) {// 使用布隆过滤器快速判断key是否可能存在,减少不必要的数据库查询if (!bloomFilter.mightContain(key)) {return "This key is likely not in the database.";}// 尝试从Redis缓存中获取数据String value = redisTemplate.opsForValue().get(key);// 如果缓存未命中,且布隆过滤器判断可能在数据库中,则查询数据库if (value == null) {value = databaseFetch(key);// 数据库中也不存在,则将空值写入缓存,设置较短过期时间以避免长时间占用缓存if (value == null) {redisTemplate.opsForValue().set(key, "", 5, TimeUnit.MINUTES);} else {// 数据库中存在,则正常缓存该值redisTemplate.opsForValue().set(key, value);}}return value;}/*** 模拟从数据库获取数据的方法,实际应用中应替换为真实的数据库访问逻辑。** @param key 数据查询键* @return 从数据库查询到的数据或null*/private String databaseFetch(String key) {// 示例中始终返回null,表示数据库中也没有该数据return null;}
}

这篇关于redis穿透解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072005

相关文章

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

利用Frp实现内网穿透(docker实现)

文章目录 1、WSL子系统配置2、腾讯云服务器安装frps2.1、创建配置文件2.2 、创建frps容器 3、WSL2子系统Centos服务器安装frpc服务3.1、安装docker3.2、创建配置文件3.3 、创建frpc容器 4、WSL2子系统Centos服务器安装nginx服务 环境配置:一台公网服务器(腾讯云)、一台笔记本电脑、WSL子系统涉及知识:docker、Frp

为什么要做Redis分区和分片

Redis分区(Partitioning)和分片(Sharding)是将数据分布在多个Redis实例或多个节点上的做法。这种技术用于提高性能、可扩展性和可用性。以下是执行Redis分区和分片的主要原因: 1. **提高吞吐量**:    - 通过将数据分散到多个节点,可以并行处理更多的操作,从而提高整体吞吐量。 2. **内存限制**:    - 单个Redis实例的内存是有限的。分区允许数据

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源

Redis-在springboot环境下执行lua脚本

文章目录 1、什么lua2、创建SpringBoot工程3、引入相关依赖4、创建LUA脚本5、创建配置类6、创建启动类7、创建测试类 1、什么lua “Lua”的英文全称是“Lightweight Userdata Abstraction Layer”,意思是“轻量级用户数据抽象层”。 2、创建SpringBoot工程 3、引入相关依赖 <?xml version

redis切换数据库的方法【jedis】

package com.test;import redis.clients.jedis.Jedis;public class readredis {public static void main(String[] args) {// 连接本地的 Redis 服务Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.select(10);String v

Redis 高性能基本操作

单元素操作是基础 单元素操作,是指每一种集合类型对单个数据实现增删改查 例如,Hash 类型的 HGET、HSET 和 HDEL,Set 类型的 SADD、SREM、SRANDMEMBER 等这些操作的复杂度由集合采用的数据结构决定,例如,HGET、HSET 和 HDEL 是对哈希表做操作,所以它们的复杂度都是 O(1)Set 类型用哈希表作为底层数据结构时,它的 SADD、SREM、SRAN

redis高级用法

redis 慢日志查询 配置参数 slowlog-log-slower-than 10000 #单位微秒 slowlog-max-len 选项指定服务器最多保存多少条慢查询日志 redis-cli slowlog get #获取慢日志1) 1) (integer) 4 # 日志的唯一标识符(uid)2) (integer) 1378781447 # 命令执

免费内网穿透工具 ,快解析内网穿透解决方案

在IPv4公网IP严重不足的环境下,内网穿透技术越来越多的被人们所使用,使用内网穿透技术的好处有很多。 1:无需公网ip 物以稀为贵,由于可用的公网IP地址越来越少,价格也是水涨船高,一个固定公网IP一年的成本要上万,而使用内网穿透技术则不需要公网IP的支持。 2:提高安全性 使用内网穿透技术,无需在路由器映射端口,我们知道黑客通常会使用端口扫描来寻找攻击对象,不映射端口能大大提高服务器的安全

redis在window下安装

1、redis简介 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hashs(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redi