8 redis持久化
RDB
把内存中单的数据生成快照保存在磁盘的过程,触发RDB持久化的过程分为手动触发和自动触发
- 手动触发
命令行使用save命令,阻塞当前redis服务器知道RDB完成
命令行使用bgsave命令,使redis进程执行fork操作创建子进程,RDB持久化由子进程负责,完成后自动结束 - 自动触发(默认支持)
redis.conf配置save选项
“save seconds change",表示seconds秒内有change个改动即进行保存 - 优点:
- RDB是一个紧凑的二进制文件,,适用于备份和全量恢复
- 加载RDB恢复数据远远快于AOF方式
- 缺点
- bgsave每次运行都要执行fork操作子进程,频繁执行成本高
- 使用特定二进制格式保存,存在版本兼容问题
- 在定时持久化之前机器宕机,无法最大限度避免数据丢失
AOF(append only file)
以独立日志方式记录每次的命令,重启时执行AOF文件中的命令恢复数据
-
优点:
- 采用append方式,即使主机宕机也不会破坏日志文件中的内容
- 日志过大时,redis启用rewrite机制,即redis以append模式不断的将修改的数据写入到老的磁盘文件中,同时redis创建一个新的文件用于记录有哪些修改命令被执行,因此在rewrite切换时可以更好的保证数据安全性
-
劣势
- 对于相同的数据集,AOF文件比RDB文件大
- 根据采用的同步策略不同,效率较RDB低
-
配置AOF
- ”appendonly yes”:开启AOF,默认关闭
- appendfsync strategy:选择策略strategy
- always:每修改同步,每次有数据改变时都会写入AOF文件
- everysec:每秒同步,AOF的缺省设置
- no:不同步
-
rewrite功能
因为所有的操作都会记录,必定会出现一些无用的日志,这会让AOF文件过大,也会让数据恢复的时间过长。因此,Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。可以在redis.conf配置定期自动进行:#日志大小增长100%时自动进行AOF rewrite auto-aof-rewrite-percentage 100 # 增长大小没有达到64mb时不会进行rewrite auto-aof-rewrite-min-size 64mb
-
缓存击穿
指用户请求的Key的数据不在Redis的缓存当中,最终只能去后端的数据库中查找请求的数据。当这种请求特别多是会对后端数据库造成很大的压力
解决方案:
加锁,只有第一个请求查询数据库,然后放入redis,后续的查询,可以设置永不过期或者设置一个较大的过期时间 -
缓存穿透
指客户端一直查询一定不存在的数据
解决方案:- id检验;不存在的数据缓存为null,超时时间设置短一点
- 利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试
- 采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作
- 提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回
-
缓存雪崩
缓存中的数据同一时间大量失效,导致全部查询落入数据库
解决方案:- 数据的过期时间随机设置,防止同时过期;热点数据永远不过期
- 使用互斥锁,但这种方法会影响系统吞吐量
- 双缓存:A设置失效时间,B不设置
- 从缓存A读数据,有则直接返回
- A中没有数据,直接从B读取,直接返回,并启动一个更新线程更新A和B