Redis持久化机制学习总结

前言:

         Redis的持久化机制是它的一大优势,关于redis持久化问题,这篇文章包含了关于持久化的一些细节。


Redis核心主流程:

       Redis的服务器进程就是一个事件循环,包括文件事件和时间事件两大核心事件。Redis服务器初始化后会无限循环,处理产生的文件事件和时间事件。

       文件事件: 主要用来接受连接,读取,写入,关闭连接等;

       时间事件: serverCron,默认配置下,每隔100ms触发一次,在该事件中又很多操作。比如更新服务器的各类统计信息,比如时间,内存占用等,清理过期键值对,关闭和清理失效的客户端,尝试进行AOF和RDB持久化操作,如果服务器是主节点的话,对附属节点进行定期同步,如果处于集群模式的话,对集群进行定期同步和连接测试。   


Redis持久化方式:

       1. RDB, 类似于快照, Redis DataBase;

       2. AOF,    Append-only file

       3. 混合持久化

RDB实现原理和优缺点:

描述:类似于快照,在某个时间点,把redis内存中的数据保存到磁盘中,RDB持久化生成的文件是经过压缩的二进制文件。

命令: 生成RDB文件的命令有两个 save 和 bgsave

开启: 配置save point,当满足save point条件后就会触发一次bgsave存储内存中的一次快照,这边save point的检测就是时间事件severCron

格式:  save point格式  save <second> <changes> 意味着Redis如果在seconds秒内数据发生了changes次改变,就会保存快照文件

save命令: 生成RDB文件会阻塞主进程,服务器在这个期间无法处理客户端发过来的其他请求

bgsave命令: 主进程会fork出子进程进行RDB快照,只会在fork期间阻塞,在生成RDB文件的过程中不会阻塞。

优点:  1. 适合做冷备,RDB是经过压缩的二进制文件,文件占用空间非常小; 2. 适合做灾难恢复,只有一个文件,可以加密后把文件发送到数据中心 ;3.对于大数据的恢复,RDB比AOF速度更快

缺点: 1. 容易造成数据丢失,因为只有达到save point条件之后才会保存一次快照; 2. 如果内存数据较大,fork子进程可能会非常耗时; 3. Linux fork子进程采用的是copy-on-write方式,在redis执行持久化期间,如果client写入数据很频繁,那么将会增加redis内存占用情况,最坏的情况,内存占用达到原来的两倍。刚fork出来,主进程和子进程共享内存,但是随着主进程需要处理写操作,主进程将修改的页面copy出来一份,然后进行修改,极端情况,所有的页面都要被修改,此时内存占用达到原来的两倍

fork():   在linux系统中,调用fork()的时候会创建出一个新的进程,称为子进程,子进程会copy父进程的page table,如果进程占用的内存越大,进程的page table也越大,那么fork就会占用更多的时间。如果redis内存占用很大,在fork期间会出现明显的停顿。

 

AOF实现原理和优缺点:

append-only file: 保存redis所有的写操作来记录数据状态,当服务器重启的时候,会重新执行这些命令来还原数据集

AOF持久化功能分三个步骤: 命令追加,文件写入,文件同步

命令追加: 当AOF持久化功能打开的时候,服务器执行完一个写命令后,会将执行的写命令追加到服务器aof缓冲区的末尾

文件写入和文件同步: 在时间事件serverCron中会触发flushAppendOnlyFile函数,该函数根据appendSync函数,决定是否将aof_buf缓冲区的数据持久化到AOF文件。缓冲区刷盘策略主要包括:

always: 每处理一个命令都从缓冲区刷盘到文件

everysec: 每秒刷盘一次

no: 由操作系统决定刷盘策略,也就是从pageCache刷盘的策略

优点: 1. 可靠性比RDB高,可以设置每秒刷盘一次,如果发生宕机,最多丢失一秒的内存数据; 2. AOF文件有序的保存了对数据库执行的所有写入操作,以Redis协议的格式保存,容易被读懂,解析也很轻松

缺点: 1. 对于相同的数据集,AOF文件比RDB大,因为RDB是经过压缩的二进制文件 2. 适合做热备,对于大数据集的恢复,AOF速度比RDB慢

 

混合持久化:

混合持久化只发生在AOF重写过程,使用混合持久化,重写后的AOF文件前半段是RDB格式的全量数据,后半段是AOF格式的增量数据。

混合持久化的本质是通过AOF后台重写完成的,当后台重写开始后,fork出的子进程把当前全量数据以RDB方式写入AOF文件,然后再将AOF重写缓冲区的命令以AOF方式写入文件。写入完成后通知主进程将新的含有RDB格式和AOF格式的AOF文件替换就的AOF文件。

优点: 结合RDB和AOF持久化方式的优点,可以更快重写和恢复,防止大量数据丢失

缺点: 可读性不如AOF,因为AOF文件里面前半部分加入了RDB格式的数据,是经过压缩的二进制。


为什么需要重写AOF:

AOF是通过记录写命令来记录内存状态的,随着命令的增加,aof文件会越来越大,如果不控制,体积过大对redis服务器甚至整个宿主机造成严重影响,体积过大,数据恢复时间也会很长。比如100次INCR操作,为了记录状态,需要记录100条命令,其实重写只需要一条命令,为了处理这种情况,aof引入重写,在不打断服务端处理请求的情况下,对aof文件进行重写。

AOF重写方法:

AOF生成新的aof文件来代替旧的aof文件,新的aof文件包含重建当前数据所需要的最少的命令,具体过程是遍历所有数据库的健,从数据库读取健现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令。

命令: BGREWRITEAOF   REWRITEAOF

REWRITEAOF:进行aof重写,但是会阻塞主进程,服务器将无法处理客户端发过来的命令请求,通常不会直接使用该命令

BGREWRITEAOF: fork子进程来进行aof重写,阻塞只发生在fork子进程的时候,之后主进程可以正常处理请求。

AOF后台重写存在的问题:

AOF后台重写使用子进程进行重写,解决了主进程阻塞的问题。但是仍然存在一个问题,子进程进行AOF重写期间,服务器主进程还会继续处理客户端请求,新的命令可能会对现有的数据库状态进行修改,从而使得当前的数据库状态和重写后的AOF文件保存的数据库状态不一致。

解决方法: 引入aof重写缓冲区(aof_rewrite_buf_blocks),这个缓冲区在子进程创建完成之后开始使用,当服务器执行完写命令后,会把命令追加到aof缓冲区和重写缓冲区。这样,当子进程完成aof重写工作后,父进程会在serverCron中检测到子进程已经重写结束,则会执行以下工作:

1. 将aof重写缓冲区中的所有内容写入到新aof文件中,这时新aof文件所保存的数据库状态将和服务器当前的数据库状态一致。

2. 对新的aof文件进行改名,原子的覆盖现有的aof文件,完成新旧两个aof文件的替换。

 


AOF重写缓冲区数据过多怎么办:

将aof重写缓冲区内容追加到aof文件这一过程是主进程进行的,如果数据量过大,会阻塞主进程,导致一段时间没法正常响应客户端请求。

解决方法:

1. 在进行aof后台重写时,redis会创建一组用于父子进程间通信的管道,同时会新增一个文件事件,该文件事件会将写入aof重写缓冲区的内容通过该管道发送给子进程;

2. 在重写结束后,子进程会通过该管道尽量从父进程读取更多的数据,每次等待可读取事件1ms,如果一直能读取到数据,则这个过程最多执行1000次,如果连续20次都没有读取到数据,则结束这个过程。

通过这种优化,Redis尽量让aof重写缓冲区的内容更少,以减少主进程阻塞的时间。

 


服务器启动如何加载持久化数据:

如果同时开启aof和rdb,则会在aof进行数据重建,因为aof相对rdb来说数据更加完整;

如果引入混合持久化, 使用 aof重建数据时,通过文件开头是否为“REDIS” 来判断是否为混合持久化。

服务重启数据重建过程:

        

 

 

 

 

            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值