Redis数据持久化
为什么要进行数据持久化
为了避免因进程退出造成的数据丢失问题,redis把内存中的数据保存在硬盘中叫做持久化,Redis提供了两种持久化的方式RDB和AOF,当下次重启的时候利用之前持久化的文件就可以恢复之前的数据。
RDB(Redis DataBase)
RDB属于是定期备份,定期的将redis的数据写入硬盘,形成一个快照
1.手动触发
通过客户端执行特定的命令,来触发快照的生成
save: 执行save的时候,redis就会停止其他服务,全力以赴的进行快照生成操作,此时就会阻塞redis的其他客户端命令,形成类似 keys * 的效果 (不建议)
bgsave: 不会影响redis服务器处理其他客户端的命令,采用多进程的方式并发编程
2.自动触发
在redis的配置文件中,根据多长时间内修改了多少次进行一次备份,执行shutdown关闭redis客户端的时候,Redis也会触发保存操作,如手动停止当前的服务其中就会包含shutdown命令,自动触发也是采用的bgsave的方式
3.bgsave的方式
客户端执行bgsave命令,父进程判断是否已经有其他子进程正在执行备份操作,如果有,直接返回,如果没有,父进程执行fork命令,创建一个子进程,然后父进程继续响应其他命令,子进程的内存数据跟fork一模一样,此处使用了写时拷贝的机制,并不真正执行拷贝操作,而是共用一个内存数据,只有这个内存数据进行了修改时,才会真正触发物理上的拷贝操作。子进程使用临时文件保存备份的快照数据,当子进程生成RDB文件完全执行成功之后,就会用信号通知父进程,进行RDB文件的的替换操作。
4.RDB文件
redis生成的rdb文件目录也是在redis的配置文件中进行配置的
redis默认就是开启了rdb的,rdb是一个二进制文件,把内存中的数据,以压缩的形式,保存在这个二进制文件中~~ 已压缩的形式会消耗一定的CPU资源,但是能节省存储空间
rdb的文件格式是不能随便改动的,redis也提供了rdb文件格式的检查工具
AOF(Append Only File)
使用文本的方式保存数据,恢复速度要比RDB慢,但是解决了RDB不能实时保存数据的问题,使用RDB在两次数据备份之间可能会因为redis重启导致数据丢失,AOF会记录用户的每一个操作,AOF默认是关闭的状态,需要修改配置文件,打开AOF。AOF的优先级高于RDB
1.写硬盘而导致的速度问题
redis不仅需要写内存有需要写硬盘,是否会导致redis的速度降低呢?
其实,是没有多大影响的
1)AOF机制并非直接让工作的线程把数据写入硬盘,而是先写入一个内存中的缓冲区,积累一波之后,再统一写入硬盘。(主要是写入次数影响性能,写入数据量多少并没有太大的影响)
2)硬盘上读写数据,顺序读写的速度是比较快的(还是比内存慢的多)随机访问则速度是比较慢的,AOF是每次把新的操作写入原文件的末尾,属于顺序写入~~
如果数据还在内存期间,redis挂了,数据还是会丢失,所以redis提供了一些配置让程序员进行取舍,制定缓冲区的刷新策略
刷新速率越高,对性能影响越大,数据可靠性越高
刷新速率越小,对性能影响越小,数据可靠性越低
通过配置appendfsync来配置redis的刷新策略
redis默认配置是everysec,每秒进行一次刷新
2.AOF文件体积持续增长,数据冗余的问题
AOF文件体积持续增长,会影响redis下次启动的时间,但是redis启动的时候,其实并不关心用于操作的过程,只关心最终的结果
因此redis就存在一个rewrite(重写操作),能针对aof文件进行整理操作。这个整理就是能够剔除其中的冗余操作,并且合并一些操作,达到瘦身的目的。(直接根据现有redis中的数据进行重写,自动重写也是在配置文件中进行配置)
3.重写操作
执行AOF重写请求,如果当前正在进行AOF重写操作,就直接返回不执行,如果当前正在执行bgsave操作,AOF重写操作会等到bgsave操作执行完毕后执行
父进程执行fork操作创建子进程
父进程继续接受客户端请求,将数据写入缓冲区,然后根据appendfsync策略写入AOF文件
子进程只有fork之前的数据,所有父进程同时要将后面的数据写入AOF重写缓冲区
子进程根据内存快照将数据写入到新的AOF文件中
子进程完成重写,新文件写入后,子进程发送信号给父进程。父进程把AOF重写缓冲区内临时保存的命令追加到新的AOF文件中,用新的AOF文件替换老的AOF文件
数据恢复过程
总结
1.redis提供了两种持久化方案:RDB和AOF
2.RDB视为内存的快照,产生的内容更加紧凑,占用空间较小,恢复时速度较快。但产生RDB的开销较大,不适合进行实时持久化,一般用于冷备和主从复制
3,AOF视为对修改命令保存,在恢复时需要重放命令。并且有重写机制来定期压缩AOF文件
4.RDB和AOF都采用fork创建子进程,利用Linux子进程拥有父进程内存快照的特点进行持久化
,尽可能不影响主进程继续处理后续命令