redis

redis 数据类型以及应用场景

  • string:验证码
  • list:订单列表
  • hash:购物车
  • set:订单列表
  • Sorted Set:排行榜

redis 持久化方式

  1. RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

在这里插入图片描述

  1. AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

在这里插入图片描述
RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:

save 900 1              #在900(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10             #在300(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000           #在60(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。

AOF持久化配置

在Redis的配置文件中存在三种同步方式,它们分别是:

appendfsync always     #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec   #每秒钟同步一次,该策略为AOF的缺省策略。
appendfsync no         #从不同步。高效但是数据不会被持久化。

参考资料:点击这里

redis 内存淘汰策略

过期策略

我们set key的时候,都可以给一个expire time,就是过期时间,指定这个key比如说只能存活1个小时,我们自己可以指定缓存到期就失效。如果假设你设置一个一批key只能存活1个小时,那么接下来1小时后,redis是怎么对这批key进行删除的?

答案是:定期删除+惰性删除

  • 所谓定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。
    实际上redis是每隔100ms随机抽取一些key来检查和删除的。

  • 但是,定期删除可能会导致很多过期key到了时间并没有被删除掉,所以就得靠惰性删除了。这就是说,在你获取某个key的时候,redis会检查一下
    ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。并不是key到时间就被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下

通过上述两种手段结合起来,保证过期的key一定会被干掉。但是实际上这还是有问题的,如果定期删除漏掉了很多过期key,然后你也没及时去查,也就没走惰性删除,此时会怎么样?如果大量过期key堆积在内存里,导致redis内存块耗尽了,怎么办?

答案是:走内存淘汰机制。

内存淘汰机制:

如果redis的内存占用过多的时候,此时会进行内存淘汰,有如下一些策略:

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧
  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适)
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

redis 缓存穿透、击穿、雪崩问题

  1. 缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
  2. 缓存击穿:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
  3. 缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

解决方式:使用setnx,配合双重锁的机制代码如下:

package com.redis.lock;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

/**
 * setNx 悲观锁 解决雪崩 击穿 穿透问题
 * 事物+监听  解决秒杀 库存卖超问题。
 */
@Component
public class RedisLockTest extends Thread {


    @Override
    public void run() {
        try {
            setNx();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    public String setNx() throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"开始获取缓存数据");
        String key = stringRedisTemplate.opsForValue().get("order");
        if (StringUtils.isNotBlank(key)){
            System.out.println(Thread.currentThread().getName()+"开始获取缓存数据成功,返回");
            return  key;
        }
        System.out.println(Thread.currentThread().getName()+"获取缓存数据失败");
        Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent("lock", "1");

        if (aBoolean){
            System.out.println(Thread.currentThread().getName()+"拿到锁成功,重新设置缓存");
            stringRedisTemplate.expire("lock",1, TimeUnit.MINUTES);
            //处理业务逻辑
            key = stringRedisTemplate.opsForValue().get("order");
            if (StringUtils.isNotBlank(key)){
                System.out.println(Thread.currentThread().getName()+"---------返回缓存数据");
                stringRedisTemplate.delete("lock");
                return  stringRedisTemplate.opsForValue().get("order");
            }
            //模拟查询数据库
            Thread.sleep(2000);
            stringRedisTemplate.opsForValue().set("order","订单号为123456");
            stringRedisTemplate.delete("lock");
            System.out.println(Thread.currentThread().getName()+"。。。。。。返回缓存数据");
            return  stringRedisTemplate.opsForValue().get("order");
        }else {
            Thread.sleep(500);
            setNx();
        }
        return null;
    }
}

redis 集群模式,以及cluster集群

参考资料:点击这里

redis 应用场景

  • 登录锁定
  • 验证码生成
  • springSecurity token
  • 分布式事务
  • 限流令牌桶

Redis哨兵怎么实现的-主节点挂掉后从节点怎么实现转为主节点的

参考资料 : 点击这里

redis 集群的三种模式优缺点

参考资料:点击这里

求一键三连,谢谢!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Carl God

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值