Redis安全策略详解

Redis安全策略详解

目录

缓存穿透

缓存击穿

缓存雪崩

布隆过滤器

基于布隆过滤器解决缓存穿透问题

缓存穿透

高并发情况下查询一个不存在的key

产生的背景(原因):

缓存穿透是指使用不存在的key进行大量的高并发查询,导致缓存无法命中,每次请求都要都要穿透到后端数据库查询,使得数据库的压力非常大,甚至导致数据库服务压死;

解决方案:

接口层实现api限流、用户授权、id检查等;

从缓存和数据库都取不到数据的话,一样将数据库空值放入缓存中,设置30s有效期避免使用同一个id对数据库攻击压力大;

布隆过滤器

缓存击穿

高并发情况下查询的一个key突然过期

产生背景(原因):

在高并发的情况下,当一个缓存key过期时,因为访问该key请求较大,多个请求同时发现缓存过期,因此对多个请求同时数据库查询、同时向Redis写入缓存数据,这样会导致数据库的压力非常大;

解决方案:

使用分布式锁

保证在分布式情况下,使用分布式锁保证对于每个key同时只允许只有一个线程查询到后端服务,其他没有获取到锁的权限,只需要等待即可;这种高并发压力直接转移到分布式锁上,对分布式锁的压力非常大。

使用本地锁

使用本地锁与分布式锁机制一样,只不过分布式锁适应于服务集群、本地锁仅限于单个服务使用。

软过过期

设置热点数据永不过期或者异步延长过期时间;

缓存雪崩

高并发情况下大量的key 集中失效

产生背景(原因):

缓存雪崩指缓存服务器重启或者大量的缓存集中在某个时间段失效,突然给数据库产生了巨大的压力,甚至击垮数据库的情况。

解决思路:对不用的数据使用不同的失效时间,加上随机数

布隆过滤器

布隆过滤器适用于判断某个数据是否在集合中存在,不一定百分百准备, Bloom Filter基本实现原理采用位数组与联合函数一起实现;

布隆过滤器最大的问题:就是可能会存在一个误判的问题,如果向误判概率越低,则二进制数组会越大,同时也会非常占用空间

基于布隆过滤器解决缓存穿透问题

maven依赖

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>22.0</version> </dependency>

测试代码

public class BlongTest { /** * 在布隆中存放100万条数据 */ private static Integer size = 1000000; public static void main(String[] args) { BloomFilter<Integer> integerBloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.01); for (int i = 0; i < size; i++) { integerBloomFilter.put(i); } // 从布隆中查询数据是否存在 ArrayList<Integer> strings = new ArrayList<>(); for (int j = size; j < size + 10000; j++) { if (integerBloomFilter.mightContain(j)) { strings.add(j); } } System.out.println("误判数量:" + strings.size()); } }

解决缓存击穿代码

@RequestMapping("/getOrder") public OrderEntity getOrder(Integer orderId) { if (integerBloomFilter != null) { if (!integerBloomFilter.mightContain(orderId)) { System.out.println("从布隆过滤器中检测到该key不存在"); return null; } } // 1.先查询Redis中数据是否存在 OrderEntity orderRedisEntity = (OrderEntity) redisTemplateUtils.getObject(orderId + ""); if (orderRedisEntity != null) { System.out.println("直接从Redis中返回数据"); return orderRedisEntity; } // 2. 查询数据库的内容 System.out.println("从DB查询数据"); OrderEntity orderDBEntity = orderMapper.getOrderById(orderId); if (orderDBEntity != null) { System.out.println("将Db数据放入到Redis中"); redisTemplateUtils.setObject(orderId + "", orderDBEntity); } return orderDBEntity; } /** * 添加订单id到布隆过滤器中 */ @RequestMapping("/dbToBulong") public String dbToBulong() { List<Integer> orderIds = orderMapper.getOrderIds(); integerBloomFilter = BloomFilter.create(Funnels.integerFunnel(), orderIds.size(), 0.01); for (int i = 0; i < orderIds.size(); i++) { integerBloomFilter.put(orderIds.get(i)); } return "success"; }

到此这篇关于Redis安全策略详解的文章就介绍到这了,更多相关Redis安全内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    redis密码设置|如何设置redis密码

    redis密码设置|如何设置redis密码,,如何设置redis密码初始化Redis密码: 在配置文件中有个参数: requirepass 这个就是配置redis访问密码的

    Redis集群批量操作

    Redis集群批量操作,节点,集群,Redis在3.0版正式引入了集群这个特性,扩展变得非常简单。然而当你开心的升级到3.0后,却发现有些很好用的功能

    redis sentinel模式命令集

    redis sentinel模式命令集,状态,频道, ping 订阅模式:ping 服务器回复:*2$4pong$0ping xxx 服务器回复:*2$4pong$3xxx其他模式ping 服

    C# 基于StackExchange.Redis.dll利用Redis实现分布式Session

    C# 基于StackExchange.Redis.dll利用Redis实现分布式Session,令牌,客户端,最近在研发一款O2O产品,考虑到分布式架构的需要,以前那一套.NET的

    REDIS|11 redis做分页

    REDIS|11 redis做分页,分页,每页,之前的数据都加载到了本地java的Map,分页如下@RequestMapping("/articles")String articles(Model mode

    softwaredistribution是什么文件夹

    softwaredistribution是什么文件夹,升级,存放,更新日志,文件,补丁下载,删除,softwaredistribution在Windows目录下,主要是用来存放WINDOWS UPDAT

    centos下redis无法连接

    centos下redis无法连接,防火墙,也会,主要是两方面的原因(1)redis.conf中bind的ip,默认是127.0.0.1,只能本地连接(体现为Could not connect to

    redis bitmap实现点赞的思路

    redis bitmap实现点赞的思路,照片,用户,bitmap简介:bitmap时一连串的二进制数字(0,1),每位所在的位置为偏移(offset),在bitmap上可以执行and、or

    redis的lua脚本多返回值

    redis的lua脚本多返回值,脚本,结果,如何在redis的lua中返回不同类型的多个返回值? lua脚本的函数支持多返回值,若redis调用lua脚本支持多返

    vcredist_x86vcredist_x64区别

    vcredist_x86vcredist_x64区别,应用程序,系统,vcredist_x86vcredist_x64区别Vcredist.exe 为 Visual C++ 应用程序安装最新的运行时组件;V