Redis持久化
- 一. RDB
- (1) save
- (2) bgsave
- (3) 总结
- 二. AOF
- (1) 重写优化
- (2) RDB和AOF的区别
引入:Redis用内存存储数据,有数据丢失的问题;
一. RDB
RDB(Redis Database Bcakup file)即Redis数据备份文件,或Redis数据快照;
即把内存中的所有数据 写入磁盘;
当Redis实例故障重启后,从磁盘读取RDB快照文件,恢复数据;
(1) save
由于Redis是单线程的,当主进程来执行RDB,则会 阻塞 其他所有请求;
但是磁盘IO比较慢!当数据比较大则耗时久;
缺点:阻塞用户请求;
场景:关机前使用; 且Redis停机时会自动执行RDB!
停机时自动存储RDB,但是宕机则不会!
(2) bgsave
后台 异步 执行,让子进程去存储,主进程不受影响;
Rrdis内部触发bgsave机制:
为什么不设置短一点?
如果触发bgsave的时间设置的太短如1s,那么执行频率就越高,而执行需要写入磁盘,如果数据量太大,则1s执行一次根本忙不过来;
fork创建子进程原理:
bgsave开始会fork主进程得到子进程,子进程共享主进程的内存数据。完成后读取内存数据写入RDB文件;
在linux中,所有进程无法操作物理内存;而是由操作系统给每个进程分配虚拟内存;而后操作系统会维护一个页表(虚拟内存和物理内存的映射),虚拟内存基于页表去物理内存读取;
执行fork时会把页表做拷贝,即把映射关系拷贝给子进程,子进程获取后对虚拟内存进行操作,这样就无需拷贝内存中的数据而直接实现内存共享;这样速度就快;
而后子进程读取数据,将其写入磁盘;替换旧的RDB为新的RDB文件;
(3) 总结
基本流程:
1.fork主进程得到子进程,共享虚拟内存空间;
2.子进程读取内存数据写入新的RDB文件;
3.用新的RDB文件替换旧的RDB文件;
RDB什么时候执行?
1.默认关闭Redis时,是阻塞的;
2.bgsave;
RDB缺点:
1.一旦宕机就丢失,存在漏洞;
2.耗时长,所以bgsave触发的时间不能太短;
二. AOF
引入:由于RDB在持久化到磁盘时间隔比较长,使用AOF可以提高安全性;
AOF(Append Only File)即追加文件,本质就是把Redis接收到的写操作命令记录在AOF文件,可以看作是命令日志文件;
类似HDFS中的Edits;
当Redis出现故障,如何恢复?
只需要读取AOF文件;
把AOF中的命令再执行一次;
AOF开启:默认是关闭的,需要手动开启;
AOF记录的频率(刷盘策略
):
always:每当接收到命令则立即由主进程将数据写到内存,同时写入AOF(磁盘中),最安全,性能最差;
everysec:先将命令放入【缓冲区】,然后每隔1秒将缓冲区数据写入AOF中,(默认);
no:即主进程只处理内存数据,然后将命令写入【缓冲区】,而缓冲区的命令合适写入AOF由操作系统来决定,性能高,安全性差;
(1) 重写优化
为了解决AOF文件过大,以及对同一个key多次操作的问题,则有 bgreweiteaof
命令可以对AOF中的命令重写优化,用最少的命令达到同样的效果:
触发重写的两个默认配置:
(2) RDB和AOF的区别
1.原理:RDB是对整个内存做快照并存入磁盘,而AOF只是记录新的命令;
2.数据完整性:RDB备份时间间隔长,不安全,可能不完整;而AOF的默认刷盘策略是everysec,每秒将缓冲区的命令写入AOF文件,数据更完整更安全;
3.文件大小:AOF较大
4.宕机恢复速度:恢复时,RDB存的是数据,直接加载比较快;而AOF存的是命令,启动后需要执行命令;
5.恢复优先级:即同时启用时,优先使用AOF(数据更完整)
6.系统资源占用:RDB占用高,大量CPU和内存消耗;AOF占用资源低,主要是磁盘IO,但是重启时会执行命令,占用高(异步);
7.使用场景:容忍数分钟的数据丢失,追求更快的启动速度选择RDB;对安全性高则用AOF或者两种结合到一起使用;