一、说下Redis的持久化⽅式RDB和AOF区别
答案:
(一)Redis持久化介绍
1、Redis是⼀个内存数据库,如果没有配置持久化,redis重启后数据就全丢失
2、因此开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
(二)两种持久化⽅式
1、RDB (Redis DataBase)
2、AOF (append only file)
(三)RDB持久化介绍
1、在指定的时间间隔内将内存中的数据集快照写⼊磁盘
2、默认的⽂件名为dump.rdb
3、产⽣快照的情况
(1)save
会阻塞当前Redis服务器,执⾏save命令期间,Redis不能处理其他命令,直到RDB过程完成为⽌
(2)bgsave
fork创建⼦进程,RDB持久化过程由⼦进程负责,会在后台异步进⾏快照操作,快照同时还可以响应客户端请求
(3)⾃动化
① 配置⽂件来完成,配置触发 Redis的 RDB 持久化条件
② ⽐如 “save m n”。表示m秒内数据集存在n次修改时,⾃动触发bgsave
(4)主从架构
从服务器同步数据的时候,会发送sync执⾏同步操作,master主服务器就会执⾏bgsave
4、优点
(1)RDB⽂件紧凑,全量备份,适合⽤于进⾏备份和灾难恢复
(2)在恢复⼤数据集时的速度⽐ AOF 的恢复速度要快
(3)⽣成的是⼀个紧凑压缩的⼆进制⽂件
5、缺点
(1)每次快照是⼀次全量备份,fork⼦进程进⾏后台操作,⼦进程存在开销
(2)在快照持久化期间修改的数据不会被保存,可能丢失数据
(四)AOF持久化介绍
1、append only file,追加⽂件的⽅式,⽂件容易被⼈读懂
2、以独⽴⽇志的⽅式记录每次写命令, 重启时再重新执⾏AOF⽂件中的命令达到恢复数据的⽬的
3、写⼊过程宕机,也不影响之前的数据,可以通过 redis-checkaof检查修复问题
4、配置
(1)appendonly yes,默认不开启
(2)AOF⽂件名 通过 appendfilename 配置设置,默认⽂件名是appendonly.aof
(3)存储路径同 RDB持久化⽅式⼀致,使⽤dir配置
5、核⼼原理
(1)Redis每次写⼊命令会追加到aof_buf(缓冲区)
(2)AOF缓冲区根据对应的策略向硬盘做同步操作
(3)⾼频AOF会带来影响,特别是每次刷盘
6、提供了3种同步⽅式,在性能和安全性⽅⾯做出平衡
(1)appendfsync always
每次有数据修改发⽣时都会写⼊AOF⽂件,消耗性能多
(2)appendfsync everysec
每秒钟同步⼀次,该策略为AOF的缺省策略。
(3)appendfsync no
不主从同步,由操作系统⾃动调度刷磁盘,性能是最好的,但是最不安全
二、说下分布式缓存必考题之缓存击穿-穿透-雪崩区别+解决⽅案
答案:
(一)缓存击穿 (某个热点key缓存失效了)
1、缓存中没有但数据库中有的数据,假如是热点数据,那key在缓存过期的⼀刻,同时有⼤量的请求,这些请求都会击穿到DB,造成瞬时DB请求量⼤、压⼒增⼤。
2、和缓存雪崩的区别在于这⾥针对某⼀key缓存,后者则是很多key。
3、预防
(1)设置热点数据不过期
(2)定时任务定时更新缓存
(3)设置互斥锁
4、SpringCache解决⽅案
(1)缓存的同步 sync
(2)sync 可以指示底层将缓存锁住,使只有⼀个线程可以进⼊计算,⽽其他线程堵塞,直到返回结果更新到缓存中
(二)缓存雪崩 (多个热点key都过期)
1、⼤量的key设置了相同的过期时间,导致在缓存在同⼀时刻全部失效,造成瞬时DB请求量⼤、压⼒骤增,引起雪崩
2、预防
(1)存数据的过期时间设置随机,防⽌同⼀时间⼤量数据过期现象发⽣
(2)设置热点数据永远不过期,定时任务定时更新
3、SpringCache解决⽅案
(1)设置差别的过时时间
(2)⽐如CacheManager配置多个过期时间维度
(3)配置⽂件 time-to-live 配置
#使⽤的缓存类型
type: redis
#过时时间
redis:
time-to-live: 3600000
# 开启前缀,默以为true
use-key-prefix: true
# 键的前缀,默认就是缓存名cacheNames
key-prefix: XD_CACHE
# 是否缓存空结果,防⽌缓存穿透,默以为true
cache-null-values: true
(三)缓存穿透(查询不存在数据)
1、查询⼀个不存在的数据,由于缓存是不命中的,并且出于容错考虑,如发起为id为“-1”不存在的数据
2、如果从存储层查不到数据则不写⼊缓存这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。存在⼤量查询不存在的数据,可能DB就挂掉了,这也是⿊客利⽤不存在的key频繁攻击应⽤的⼀种⽅式。
3、预防
(1)接⼝层增加校验,数据合理性校验
(2)缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,设置短点的过期时间,防⽌同个key被⼀直攻击
4、SpringCache解决⽅案
空结果也缓存,默认不配置condition或者unless就⾏
cache:
#使⽤的缓存类型
type: redis
#过时时间
redis:
time-to-live: 3600000
# 开启前缀,默以为true
use-key-prefix: true
# 键的前缀,默认就是缓存名cacheNames
key-prefix: XD_CACHE
# 是否缓存空结果,防⽌缓存穿透,默以为true
cache-null-values: true