温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Redis安全策略实例分析

发布时间:2022-07-28 09:59:19 来源:亿速云 阅读:100 作者:iii 栏目:开发技术

本文小编为大家详细介绍“Redis安全策略实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Redis安全策略实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

缓存穿透

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

产生的背景(原因):

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

解决方案:

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

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

  3. 布隆过滤器

缓存击穿

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

产生背景(原因):

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

解决方案:

  1. 使用分布式锁

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

  1. 使用本地锁

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

  1. 软过过期

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

缓存雪崩

高并发情况下大量的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安全策略实例分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI