Redis-安全

缓存穿透

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

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

解决方案:

  1. 接口层实现api限流、用户授权、id检查等;
  2. 从缓存和数据库都取不到数据的话,一样将数据库空值放入缓存中,设置30s有效期避免使用同一个id对数据库攻击压力大;
  3. 布隆过滤器

缓存击穿

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

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

解决方案:

  1. 使用分布式锁
    保证在分布式情况下,使用分布式锁保证对于每个key同时只允许只有一个线程查询到后端服务,其他没有获取到锁的权限,只需要等待即可;这种高并发压力直接转移到分布式锁上,对分布式锁的压力非常大。
  2. 使用本地锁
    使用本地锁与分布式锁机制一样,只不过分布式锁适应于服务集群、本地锁仅限于单个服务使用。
  3. 软过过期
    设置热点数据永不过期或者异步延长过期时间;

缓存雪崩

高并发情况下大量的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";
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis-shake 3是Redis数据同步工具的一个版本。它是一个开源的工具,用于实现Redis数据的快速、安全和可靠地迁移、同步和备份。Redis-shake 3提供了多种灵活的同步方式,使用户可以根据自己的需求选择适合的同步模式。 Redis-shake 3具有以下特点: 1. 高效快速:采用多线程、多连接等技术手段,能够以高速并发的方式同步和迁移大规模的Redis数据。 2. 安全可靠:支持数据的断点续传,确保同步过程中的数据不丢失和不重复,同时具备数据一致性的保证。 3. 灵活性强:支持全量同步和增量同步两种模式,用户可以根据需求选择适合的同步方式。 4. 高可用性:支持故障自动切换和容灾备份,能够保证Redis服务的高可用性。 5. 提供丰富的监控和报警功能,用户可以实时监控Redis同步的状态和性能指标。 使用Redis-shake 3进行数据同步时,需要在目标Redis实例和源Redis实例之间正确配置相应的参数,例如连接地址、端口、密码等。一旦配置完成,Redis-shake 3将会自动进行数据的同步和迁移。用户可以通过监控工具实时查看同步的进度和性能情况,并监控同步的成功与否。 总而言之,Redis-shake 3是一款功能强大、性能高效的Redis数据同步工具,它能够帮助用户快速、安全和可靠地进行Redis数据的迁移、同步和备份。无论是大规模的数据迁移还是实时的数据同步,Redis-shake 3都能够提供可靠的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值