Redis

发布于:2025-07-18 ⋅ 阅读:(13) ⋅ 点赞:(0)

一.什么是Redis?

redis是一款非关系型数据(key-value),主要作用是用来作为数据缓存,数据可以存储在内存中.

二.为什么要用Redis?

        mysql中的数据直接存储在硬盘上的,每次查询连接mysql从硬盘上查询,

        所以将一些更新较少(例如新闻类型、商品类型),短时间内查询较多的(秒杀,抢购)

        从内存中查询数据,减轻了mysql的压力

三.Redis在项目中的作用?

缓存

计数器 incr key 值加1 decr key 值减1 点赞

排行榜 zset 排序

数据排重 set 不能存储重复元素

消息队列 list rput lpop

分布式锁 微服务中用到分布式

四.Redis线程模型

redis6.0之前是严格意义上的单线程,执行命令和处理客户端连接都是由一个线程完成的.

redis6.0之后引入了多线程,把处理客户端连接的任务交给一部分线程完成,

             执行命令仍然由一个单线程完成,这样保证并发安全(访问量再大,都是一个一个的执行)

五.为什么是单线程执行命令,为什么还这么快

操作都是在内存中

底层基于哈希结构,查询/操作时,可以通过key计算出哈希值,快速的定位到位置

单线程模式,避免执行命令时,线程的切换.

六.Redis持久化

redis数据默认存储在内存中,一旦断电数据就没有了

所以redis提供了数据持久化功能

有两种持久化方式:

        rdb方式:Redis DataBase 以快照方式,将redis中的数据写入到一个dump.rdb文件中

        当满足条件时,自动执行, 也是redis中默认开启的持久化方法

自动持久化条件

save 900 1      900秒 有一次key的变化

save 300 10

save 60 10000

也可以直接执行save命令,主动的持久化

AOF方式:以日志的方式,记录redis中执行的写操作命令(set del),当下次还原是,执行日志文件,逐行执行命令,还原数据.

redis中默认没有开启aof持久化方式,如果需要开启,在redis配置文件中修改

以通过 appendfilename 参数修改

AOF同步机制

appendfsync always

#每次修改都会 sync。消耗性能

appendfsync everysec #每秒执行一次 sync,可能会丢失这1s的数据(默认)

重启 redis 生效

定时任务 例如点赞数量 redis-->mysql

七.Redis事物

redis中的事务,是将我们要执行的多条命令进行打包,当执行事务中的多条命令时作为一个整体,期间是不能插入其他命令,保证命令执行的原子性,但是执行时,又不保证命令执行成功的原子性,例如三条指令,两条成功,一条失败,即使有执行失败,不会让这三条命令回滚.

multi 开始事务

        set a aa

        set b bb

        incr a

exec 执行事务

redisTemplate.multi(); 开启事务
            ValueOperations valueOperations = redisTemplate.opsForValue();字符类型
            valueOperations.set(k,v);
            valueOperations.set();
            valueOperations.set();
            valueOperations.set();`
redisTemplate.exec();执行事务

八.Key过期策略

redis中的key可以进行定时存储

valueOperations.set(k,v, 5, TimeUnit.MINUTES);

key的过期策略,说的是,key的到期时间到达后,redis以何种机制删除到期的key

惰性删除:在key过期时间到达后,不会立即删除,只是将key的状态改为不可用,当下次使用时,才会删除过期的key

定期删除:在key过期时间到达后,将key的状态改为不可用,定时定期的主动删除过期的key

key会绑定一个回调函数,到期后,自动将状态给为不可以

九.缓存穿透、缓存击穿、缓存雪崩

1.缓存穿透(重点)

        当查询一个数据库中没有的数据时(例如id=-1),redis没有,我们就去数据查询,此时缓存没有,被穿透了

        如果别人恶意攻击,也会穿过redis,直接到达mysql,可能导致mysql崩溃

解决方案:

        1.当mysql查询没有时,可以向redis也存放key-value value可以为aaa(标记),当从redis中取出值为aaa,表名mysql不存在,不再查询了

        2.对参数的合法性进行验证,例如id没有-1的

        3.使用布隆过滤器,进行验证

2.缓存击穿

        数据库中数据存在,redis中的某个热点key突然过期,此时有大量请求同时到来,发现redis中没有,大量的请求查询mysql,导致mysql崩溃

解决方案:

        1.热点数据设置较长过期时间

        2.查询mysql时加锁,还可以在锁内二次判断是否已经查询到了,如果查询到了就不在查询mysql了

3.缓存雪崩

大量的key过期


网站公告

今日签到

点亮在社区的每一天
去签到