Redis如何实现数据不丢失
Redis的读写操作都是在内存中,所以Redis性能才会高,但是当Redis重启后,内存中的数据就会丢失,那为了保存内存中的数据不会丢失,Redis实现了数据持久化机制,会把数据保存到磁盘,这样Redis重启就能够从磁盘恢复原有的数据
Redis提供了三种数据持久化方式
AOF日志:每执行一条写操作命令就把该命令以追加的方式写入一个文件里
RDB快照:将某一时刻的内存数据以二进制的方式写入磁盘
混合持久化:集成了AOF与RDB的优点
AOF
AOF步骤
Redis在执行完一条命令后就会把该命令以追加的方式写到一个文件,然后Redis重启时,会读取该命令然后逐一执行命令的方式来进行数据恢复
why先执行命令后写入磁盘?
避免额外的检查开销:因为如果先将写操作记录到AOF日志中,再执行该命令的话,如果当前命令有问题如果不检查的话,Redis使用该命令进行恢复的时候就可能会出错
不会阻塞当前写操作命令的执行:因为是在当前线程的写操作之后
- 数据可能会丢失:当前线程执行完命令而还没有写入磁盘时就宕机了
- 可能阻塞其它操作:因为记录AOF日志也是在主线程中执行,所以当Redis把日志写入磁盘时会阻塞后续的命令
AOF的写回策略
Always:每次写操作命令都会执行完后,同步AOF日志数据写回硬盘
Everysec:每次写操作命令执行完后,先写入AOF日志缓冲区,每秒写回磁盘
No:不由Redis控制写回磁盘,每次都写入AOF日志缓冲区,再由操作系统决定何时写回磁盘
AOF日志文件过大怎么办?
AOF日志是一个文件,随着写命令的执行,文件会越来越大,如果文件过大就会带来性能问题,比如AOF恢复中执行的命令就会很多就会导致恢复过程很慢
所以Redis提供了AOF重写机制,当AOF文件大小超过设定的阈值时AOF就会启用重写机制来压缩AOF文件,比如set name lixiaobo 与set name lidabo 就会设置为一条指令set name lidabo
重写AOF日志过程
Redis的重写AOF过程是由后台子进程bgwriteaof来完成的,这么做的好处:
1、子进程进行AOF重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程
2、子进程带有父进程的数据副本,之所以不使用多线程是因为多线程会共享内存那么修改时候就需要加锁来保证数据安全而这样就会降低性能。而使用子进程,创建子进程时候父子进程是共享内存数据,而当父子进程任意一方修改就会发生写时复制
触发重写机制后,主进程会创建重写AOF的子进程,此时子进程只会对这个内存进行只读,重写AOF子进程会读取所有指令,并逐一把内存数据的键值对转换成另一条命令,再将命令记录到重写日志(新的AOF文件)
但是重写过程中,主进程依然可以正常处理命令,所以就出现了问题,如果主进程修改了已经存在的key-value,那么就会发生写时复制,此时这个key-value数据在子进程的内存数据就与主进程的内存数据不一样了
为了解决这种数据不一致,Redis设置了一个AOF重写缓冲区,这个缓冲区在创建bgwriteaof子进程之后开始使用
在重写AOF期间,当Redis执行完一个写命令之后,它会同时把这个写命令放入AOF缓冲区与AOF重写缓冲区
也就是说在bgwriteaof期间,主进程需要执行三个工作
1、 执行客户端发来的命令
2、将执行后的命令写入AOF缓冲区
3、将执行后的命令写入AOF重写缓冲区
当子进程重写完成之后会向主进程发送一条信号,信号是进程间通信的一种方式
主进程收到该信号后,会调用一个信号处理函数
1、将AOF重写缓冲区中的所有内容追加到新的AOF文件中,使得新旧两个AOF所保存的数据一致
2、新的AOF的文件进行改名,覆盖现有的AOF文件
RDB
RDB记录的是某一个瞬间的内存数据,记录的是实际数据,因此在数据恢复时,RDB恢复数据的效率比AOF高些
如何进行RDB
redis提供了两个命令来执行RDB
save:执行save会在主线程生成RDB文件,所以会阻塞主线程
bgsave:创建一个子进程来生成RDB文件,避免阻塞主线程
Redis的快照是全量快照,也就是每次执行快照都会把内存中的数据都记录到磁盘,所以这是一个比较重的操作
RDB执行快照时候数据能修改?
可以修改,在执行bgsave过程,Redis依旧可以继续处理操作命令,也就是数据是能被修改,关键技术还是写时复制
混合持久化
混合持久化步骤
AOF的优点是丢失数据少,但是数据恢复慢,而RDB是优点是恢复速度快而快照的频率不好把握,如果频率过低,数据丢失的量就比较多,如果频率高就会影响性能
所以退出了混合持久化集成两者优点,在AOF重写日志时,fork出来的子进程会把当前主线程共享的内存数据以RDB方式写入到AOF文件,然后主线程处理的命令被记录到重写缓冲区中,重写缓冲区中的命令会以追加AOF的形式存在AOF日志中
混合持久化的优缺点
优点
集成了AOF与RDB的优点
缺点
文件可读性变差