redis的原理分析-redis是如何持久化的?

redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式,前者会根据指定的规则定时将内存中的数据存储到硬盘上。而后者在每次执行命令后讲命令本身记录下来,两种持久化方式可以单独使用其中的一种,也可以把这两种方式结合使用。

RDB方式

当符合一定条件时,redis会单独创建(fork)一个子进程来执行持久化,会先将数据写入到一个临时文件中,等到持久化过程都结束了,再用这个临时文件替换上次的持久化文件,整个过程中是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,并且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF更加高效,RDB的缺点就是最后一次持久化的数据可能丢失

--fork的作用是复制一个与当前进程一样的进程,新进程的所有数据(环境变量,变量,程序计数器等)数值都和原来进程一养,但是是一个全新的进程,并且为原进程的子进程。

redis会在以下几种情况下对数据进行快照:

1.根据配置规则进行自动快照

2.用户执行save或者gbsave命令

3.执行flushall命令

4.执行复制replication时

根据配置规则进行自动快照

redis允许用户自定义快照条件,当符合快照条件时,redis会自动执行快照操作,快照的条件可以由用户早配置文件中配置,格式如下:

save

第一个参数是时间窗口,第二个是键的个数,也就是说,在第一个时间参数配置范围内被更改的键的个数大于后面的changes时,就是符合快照的条件,redis默认了配置了三个规则

save 900 1

save 300 10

save 60 10000

每条快照规则占一行,每条规则之间是或的关系,在900秒之内有一个以上的键被更改则进行快照。

用户执行save或者gbsave命令

除了让Redis自动进行快照以外,当我们对服务进行重启或者服务器迁移我们需要人工去干预备份。redis提供了两
条命令来完成这个任务

1.save命令

当执行save命令时,redis同步做快照操作,在快照执行过程中会阻塞所有来自客户端的请求,当redis内存中的数量较多时,通过这个命令会导致redis长时间不响应,所以不推荐使用,推荐使用bgsave

2.bgsave命令

bgsave命令可以再后台异步的进行快照操作,快照的同时服务器还可以继续响应客户端的请求,执行bgsave后,redis会立即返回ok表示开始执行快照操作

通过lastsave命令可以获取最近一次成功执行快照的时间。(自动快照采用的是异步快照操作)

执行flushall命令

该命令在前面讲过,会清除redis在内存中的所有数据。执行该命令后,只要redis中配置的快照规则不为空,也就
是save 的规则存在。redis就会执行一次快照操作。不管规则是什么样的都会执行。如果没有定义快照规则,就不
会执行快照操作

执行复制时

该操作主要是在主从模式下,redis会在复制初始化时进行自动快照。这里只需要了解当执行复制操作时,及时没有定义自动快照规则,并且没有手动执行过快照操作,它仍然会生成RDB快照文件

AOF方式

AOF的开启

默认情况下redis没有开启AOF方式的持久化,可以通过appendonly参数启用,在redis.conf中找到appendonly yes

开启AOF持久化后每执行一条会更改redis中的数据的命令后,redis就会将该命令写入到硬盘中的AOF文件中,AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是apendonly.aof,可以再redis.conf中属性appendfilename appendonlyh.aof处修改

AOF的实现

AOF文件已纯文本的形式记录redis执行的写命令,例如开启AOF持久化情况下执行如下4条命令

set foo 1

set foo 2

set foo 3

get

redis会将前3条命令写入到AOF文件中,通过vim的方式,可以看到aof文件中的内容

我们会发现AOF文件的内容正是redis发送的原始通信协议的内容,从内容中我们发现redis只记录了3条命令,然后这时有一个问题是前面2条命令其实是冗余的,因为这两条的执行结果都会被第三条命令覆盖,随着执行的命令越来越多,AOF文件也越来越大,其实内存中实际的数据可能没有多少,那这样就会造成磁盘空间以及redis数据还原的过程比较长的问题,因此我们希望redis可以自动优化AOF文件,就上面这个例子来说,前面两条是可以被删除的,而实际上redis也考虑到了,可以配置一个条件,每当达到一定条件时,redis就会自动重写AOF文件,这个条件的配置位

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

auto-aof-rewrite-percentage 表示的是当目前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会
再次进行重写,如果之前没有重写过,则以启动时AOF文件大小为依据

auto-aof-rewrite-min-size 表示限制了允许重写的最小AOF文件大小,通常在AOF文件很小的情况下即使其中有很
多冗余的命令我们也并不太关心。

另外,还可以通过bgrewriteaof 命令手动执行AOF,执行完以后冗余的命令已经被删除了

在启动时,redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,载入的速度相对于RDB会慢一些

AOF的重写原理

redis可以再AOF文件体积变得过大时,自动的在后台对AOF文件进行重写:重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。

 

重写的流程是这样的:主进程会fork一个子进程出来进行AOF重写,这个重写过程并不是基于原来的AOF文件来做的,而是有点类似于快照的方式,全量遍历内存中的数据,然后逐个序列化到AOF文件中。在fork子进程这个过程中,服务端仍然可以对外提供服务。

那这个时候重写的aof文件的数据和redis内存数据不一致了?这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf文件中,也就是单独开辟一块缓存来存储重写期间收到的数据,当子进程重写完以后,再把单独开辟的缓存数据追加到新的aof文件中。

当所有的数据全部追加到新的aof文件中后,把新的aof文件重命名,此后所有的操作都会被写入新的aof文件。如果在rewrite过程中出现故障,不会影响原来aof文件的正常工作,只有当rewrite完成后才会切换文件。因此这个rewrite过程是比较可靠的。

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值