1.Redis持久化机制
Redis持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失;有两种方式 RDB(默认) 和AOF机制
1.1RDB机制
RDB是Redis默认的持久化方式,按照一定时间将内存的数据以快照的方式保存到硬盘中,对应的数据文件dump.rdb
1.1.1手动触发RDB的操作有两个:save和bgsave
save命令:执行save命令时就会触发持久化,与此同时redis处于阻塞状态,持久化完成才会响应其他命令
bgsave命令:开启一个子进程来完成持久化操作
1.1.2自动触发RDB:
save m n : 在m秒内有n个键发生变化则自动触发持久化
1.1.3使用flushall命令时回自动触发持久化
1.1.4 RDB 优缺点
RDB 优点
RDB 的内容为二进制的数据,占用内存更小,更紧凑,更适合做为备份文件; RDB 对灾难恢复非常有用,它是一个紧凑的文件,可以更快的传输到远程服务器进行 Redis 服务恢复; RDB 可以更大程度的提高 Redis 的运行速度,因为每次持久化时 Redis 主进程都会 fork() 一个子进程,进行数据持久化到磁盘,Redis 主进程并不会执行磁盘 I/O 等操作; 与 AOF 格式的文件相比,RDB 文件可以更快的重启。
RDB 缺点
因为 RDB 只能保存某个时间间隔的数据,如果中途 Redis 服务被意外终止了,则会丢失一段时间内的 Redis 数据; RDB 需要经常 fork() 才能使用子进程将其持久化在磁盘上。如果数据集很大,fork() 可能很耗时,并且如果数据集很大且 CPU 性能不佳,则可能导致 Redis 停止为客户端服务几毫秒甚至一秒钟。
1.2AOF机制
AOF 可以把 Redis 每个键值对操作都记录到文件(appendonly.aof)中。当重启Redis会重新将持久化的日志中文件恢复数据.当两种方式同时开启时数据恢复Redis会优先选择AOF恢复
1.2.1AOF持久化策略
-
always:每条 Redis 操作命令都会写入磁盘,最多丢失一条数据;
-
everysec:每秒钟写入一次磁盘,最多丢失一秒的数据;
-
no:不设置写入磁盘的规则,根据当前操作系统来决定何时写入磁盘,Linux 默认 30s 写入一次数据至磁盘。
1.3.1优缺点
AOF 优点
1.AOF 持久化保存的数据更加完整,AOF 提供了三种保存策略:每次操作保存、每秒钟保存一次、跟随系统的持久化策略保存,其中每秒保存一次,从数据的安全 性和性能两方面考虑是一个不错的选择,也是 AOF 默认的策略,即使发生了意外情况,最多只会丢失 1s 钟的数据;
2.AOF 采用的是命令追加的写入方式,所以不会出现文件损坏的问题,即使由于某些意外原因,导致了最后操作的持久化数据写入了一半,也可以通过 re dis- check-aof 工具轻松的修复; 3.AOF 持久化文件,非常容易理解和解析,它是把所有 Redis 键值操作命令,以文件的方式存入了磁盘。即使不小心使用 flushall 命令删除了所有键值信息,只要 使用 AOF 文件,删除最后的 flushall 命令,重启 Redis 即可恢复之前误删的数据。
AOF 缺点
-
对于相同的数据集来说,AOF 文件要大于 RDB 文件;
-
在 Redis 负载比较高的情况下,RDB 比 AOF 性能更好;
-
RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 更健壮。
2.Redis淘汰策略
当 Redis 内存使用达到最大内存限制时,如果继续进行写入操作会导致 Redis 服务崩溃。因此,为了保证 Redis 服务的稳定性,Redis 在内存使用达到最大限制时采取一系列措施,如内存淘汰、警告等。
-
LRU(Least Recently Used):LRU算法会淘汰最近最少被访问的键。在Redis中,每个键都有一个时间戳,表示最后一次被访问的时间。当内存不足时,Redis会选择最久未被使用的键进行淘汰。
-
LFU(Least Frequently Used):LFU算法会淘汰使用频率最低的键。Redis中维护了每个键被访问的频率计数器。当内存不足时,Redis会选择访问频率最低的键进行淘汰。
-
TTL(Time To Live):Redis中可以为键值对设置过期时间(TTL)。当设置了TTL的键到达过期时间时,Redis会自动删除该键值对,释放空间。
-
Random:随机淘汰策略,Redis随机选择一个键进行淘汰。这种策略简单且具有随机性,但并不能保证淘汰长时间未被使用的键。
-
Allkeys-LRU:基于LRU算法,应用于所有键,不仅限于设置了过期时间的键。这意味着即使键没有过期,也可能被淘汰。
-
Volatile-LRU:基于LRU算法,只应用于设置了过期时间的键。这样可以保证只有带有过期时间的键才会被淘汰。
-
Allkeys-LFU:基于LFU算法,适用于所有键。所有键的访问频率都会被考虑在内。
-
Volatile-LFU:基于LFU算法,只应用于设置了过期时间的键。只有带有过期时间的键才会参与LFU算法的计数。
3.Redis的主从复制
主从模式中,Redis部署了多台机器,有主节点,负责读写操作,有从节点,只负责读操作。从节点的数据来自主节点,实现原理就是主从复制机制
3.1为什么使用主从复制
-
Redis载荷有限,访问量大时Redis承载不了
-
单节点Redis不能保证高可用,宕机时会导致缓存不可用
-
单台Redis实例只能利用单个核心
3.2主从复制的优点
实现了数据的热备份
如果master宕机,可使用哨兵模式,将一个slave作为新的master
负载均衡
3.2主从复制的缺点
所有写操作都是先在Master上操作,然后同步更新到Slave上,所以会有一定的延迟
3.3哨兵模式
监控Redis集群中Master以及它的slave的状态,如果某个master服务宕机,哨兵会把这个master下的某个从服务成绩为master来替代已宕机的master继续工作
tip:
-
即使过段时间宕机的master恢复了也不会便会master了,而是作为slave服务
-
哨兵模式是实现Redis高可用的解决方案
4.Redis的集群模式
5.Redis的事务处理
Redis事务不是原子性的
5.1相关命令
-
MULTI:标识一个事务的开启,即开启事务;multi
-
EXEC:执行事务中的所有命令,即提交;
-
DISCARD:放弃事务;和回滚不一样,Redis事务不支持回滚。
-
WATCH:监视Key改变,用于实现乐观锁。如果监视的Key的值改变,事务最终会执行失败。
-
UNWATCH:放弃监视。
6.Redis与缓存的关系
7.Redis的并发控制
8.Redis的应用场景
缓存
会话存储
消息队列
分布式锁 (setnx明林实现 set命令带参数实现 lua脚本实现)
地理位置和地理搜索
计数器排行榜
9.Redis和DB数据库一致性处理
1.读写双写:
在更新数据库之前,先更新Redis缓存. 在读数据时,先从Redis中获取,如果缓存不存在,则从数据库中读取,并将读取到的数据放入Redis缓存中
2.写后更新
在更新数据库后,异步更新Redis缓存,使Redis缓存的更新稍有延迟
3.定时刷新
定期刷新Redis缓存
4.发布/订阅
使用Redis的发布/订阅功能,订阅数据库中的更新时间,在更新发生时通知Redis缓存进行响应的更新
10.什么是缓存击穿、缓存穿透、缓存雪崩?
10.1缓存穿透
指查询一个一定不存在的数据时,每次查询都要访问数据库,进而给数据库带来压力
10.1.1如何避免
-
如果是非法请求,在API入口,对参数进行校验,过滤非法值
-
如果查询数据库魏空,可以给缓存设置个空值,
-
使用布隆过滤器判断数据是否存在
10.2缓存击穿
单个的热点key过期时,同一时间关于这个key的操作并发量过多,给数据库带来压力
10.2.1如何避免
-
热点数据设置不过期
-
使用互斥锁,避免大量请求同时查询数据库
-
熔断、降级,防止系统崩溃
-
对热点数据进行多级缓存
10.3缓存雪崩
数据库和Redis都有这些数据但是都过期了,或者Redis宕机,同一时间缓存大面积失效,大量请求直接访问数据库导致缓存雪崩
10.3.1如何避免
-
热点数据不过期
-
数据的过期时间不要全一致
-
分布式部署,将热点数据打散分布到多个节点
-
如果是Redis宕机,需要尽可能保证Redis的高可用性,可以搭建Redis集群,提前做好预警机制