Redis高级

Redis持久化

由于Redis数据保存在内存中,所以突然断电会导致数据丢失,为了避免数据的丢失,就需要将数据保存到磁盘文件上。

持久化策略

AOF:默认每秒对数据进行持久化

RDB:按条件触发持久化操作,满足任意一个条件

        ①900 1 900秒中修改1次

        ②300 10 300秒中修改10次

        ③60 10000 60秒中修改10000次

也可以在redis.conf文件中手动配置

AOF:每秒都进行持久化操作,所以安全性比较高,对性能要求高

RDB:按条件进行持久化操作,所以安全性比较低,对性能要求低

 这两种也可以一起用,一起用以后数据几乎不可能丢失

Redis淘汰策略

8种策略:
volatile-lru,针对设置了过期时间的key,使用lru算法进行淘汰。
allkeys-lru,针对所有key使用lru算法进行淘汰。
volatile-lfu,针对设置了过期时间的key,使用lfu算法进行淘汰。
allkeys-lfu,针对所有key使用lfu算法进行淘汰。
volatile-random,从所有设置了过期时间的key中使用随机淘汰的方式进行淘汰。
allkeys-random,针对所有的key使用随机淘汰机制进行淘汰。
volatile-ttl,删除生存时间最近的一个键。
noeviction(默认),不删除键,值返回错误。
主要是4种算法,针对不同的key,形成的策略。


算法:

lru 最近很少的使用的key(根据时间,最不常用的淘汰)
lfu 最近很少的使用的key (根据计数器,用的次数最少的key淘汰)
random 随机淘汰
ttl 快要过期的先淘汰


key :

volatile 有过期的时间的那些key
allkeys 所有的key

Redis并发问题与解决方案

1.雪崩

        ①Redis热点数据同时过期,大量请求全部打到MySQL,MySQL宕机

        解决方法:将热点数据过期时间设置为随机值,避免同时过期

        ②单个Redis服务出现问题或重启

        解决方法:配置Redis集群,解决单点故障问题

2.击穿

        击穿大量并发请求访问Redis同一个数据,还没有向Redis保存,有大量线程同时访问,导致          MySQL压力过大

        解决方法:通过双检锁实现线程同步执行

@Override
    public Student getStudentById(Long id) {
        //获得字符串操作对象
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        //先查询Redis
        Student stu = (Student) ops.get(PREFIX + id);
        if(stu == null) {
            synchronized (this) {
                System.out.println("进入了同步锁");
                //先查询Redis
                stu = (Student) ops.get(PREFIX + id);
                //如果Redis缓存存在数据,就直接返回
                if (stu != null) {
                    System.out.println("Redis查到,返回" + stu);
                    return stu;
                }
                //如果Redis没有查到数据,就查询MySQL
                stu = studentMapper.selectById(id);
                //MySQL查到数据,就保存到Redis
                if (stu != null) {
                    System.out.println("MySQL查到,返回" + stu);
                    ops.set(PREFIX + id, stu);
                    return stu;
                }
            }
        }else {
            System.out.println("没有执行同步锁");
        }
        return stu;
    }

3.穿透

        大量请求访问MySQL没有的数据,Redis缓存无法命中,导致数据库压力过大

        解决方法: 使用布隆过滤器筛选掉不存在的数据

public Student getStudentById(Long id) {
        //获得字符串操作对象
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        //先查询Redis
        Student stu = (Student) ops.get(PREFIX + id);
        if(stu == null) {
            synchronized (this) {
                System.out.println("进入了同步锁");
                //先查询Redis
                stu = (Student) ops.get(PREFIX + id);
                //如果Redis缓存存在数据,就直接返回
                if (stu != null) {
                    System.out.println("Redis查到,返回" + stu);
                    return stu;
                }
                //使用布隆过滤器判断数据库中是否存在该id
                if(rBloomFilter.contains(String.valueOf(id))) {
                    //如果Redis没有查到数据,就查询MySQL
                    stu = studentMapper.selectById(id);
                    //MySQL查到数据,就保存到Redis
                    if (stu != null) {
                        System.out.println("MySQL查到,返回" + stu);
                        ops.set(PREFIX + id, stu);
                        return stu;
                    }
                }else{
                    System.out.println("布隆过滤器判断id数据库不存在,直接返回");
                }
            }
        }else {
            System.out.println("没有执行同步锁");
        }
        return stu;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值