Redis 持久化

Redis 持久化分为AOF 持久化和RDF持久化

AOF 持久化

AOF 全称 Append Only File,这种方式会将服务器执行的所有写操作命令单独保存在日志文件中。在服务器启动时,通过加载并执行日志文件中的命令来恢复数据。这个日志文件就叫做AOF文件。

在默认情况下,AOF持久化并没有被开启,需要配置redis.conf文件中的appendonly.aof  yes 来开启。

AOF持久化实现

当开启AOF持久化后,服务器每执行一条命令,这条命令都会被追加到缓冲区aof_buf。Redis 服务器进程是一个事件循环,在一个事件循环中会循环处理不同类型的事件,其中文件事件负责接收并执行客户端的命令请求,使得一些命令被追加到aof_buf中。在结束一次事件循环之前,会调用flushAppendOnlyFile函数来决定是否将aof_buf中的命令写入并同步到AOF文件中。(注意这里的写入和同步是两个过程。在操作系统中,为了提高io操作的效率,在写入文件时,先将数据写入内存缓存区,当达到特定条件时,再一次性将缓冲区的数据同步到磁盘。这样就减少了io操作的次数,提高了系统的效率)flushAppendOnlyFile函数的运行和Redis服务器的appendfsync 同步策略参数有关。

当appendfsync参数值为always时,每执行一次事件循环,缓冲区aof_buf中的所有内容都将写入并同步到AOF文件中。即使 Redis 服务器 出现 故障, 也只会丢失最近一次事件循环中的命令数据。这种策略是最安全但是最低效的,加大了磁盘I/O负载,大大影响了redis服务器性能。

当appendfsync参数值为no时,每执行一次事件循环,将缓冲区aof_buf中的内容写入文件系统缓存当中,并不会立即同步到磁盘。至于什么时候进行同步,则由操作系统决定,通常的同步周期为30秒。一旦系统发生故障,会丢失大量的数据,但由于不执行AOF文件同步操作,写入AOF文件的效率很高

当appendfsync参数值为everysec时,每执行一次事件循环,将缓冲区aof_buf中的内容写入文件系统缓存当中,专门由一个文件同步线程,每隔一秒进行文件同步操作。这种策略兼顾性能和安全性,是一种折中的办法。

AOF文件重写

AOF存储的是所有的写操作命令,随着Redis服务器运行时间的增长,AOF文件大小会持续膨胀。AOF文件可能存在冗余的命令,比如对于一条记录,连续修改,就会保存多条写记录,实际上只需要最后一次。因此需要对AOF文件进行重写,去掉冗余的记录从而达到了减少AOF文件大小的目的。实际上AOF文件重写是将redis服务器中的数据转化为写命令,然后同步到新的AOF文件当中,用新的AOF文件替换旧的AOF文件,这个替换的过程就叫重写,新的AOF文件就不会出现冗余的命令,同时一些过期数据的写命令就被清除了,删除数据的命令也被清除了,达到了减少文件大小的目的。

AOF文件重写的实现方式

AOF文件重写时,出于性能考虑,会fork()出一个子进程来进行重写操作,Redis服务器依然处于运行状态,会处理客户端请求,并不会被阻塞。两者同时进行,主进程在运行,子进程又在重写,关键在于如何保证重写后父子进程数据的一致性。

在创建子进程时,AOF文件重写缓存区会被使用。子进程拥有redis服务器数据的副本,当Redis 服务器执行写命令时,会将写命令同时存放在aof_buf缓存区和AOF文件重写缓存区。当子进程将副本数据同步新的AOF文件中后,会发送一个信号给父进程,父进程收到信号后,会进入阻塞状态,不处理用户命令直到将AOF文件重写缓存区中的数据同步到新的AOF文件当中并完成新旧AOF文件的替换。AOF文件重写缓存区中的写命令就是子进程在重写期间,父进程接收到的新命令。在整个AOF文件后台重写的过程中,只有在信号处理函数执行的过程中,服务器进程才会被 阻塞,在其他时候不存在阻塞 情况。

RDB持久化

RDB持久化是在指定的时间间隔内,自动将内存中的所以数据生成一个副本用二进制文件存储在磁盘上,这个过程就是快照。

RDB持久化发生的条件

1、根据redis配置文件中的设置的条件触发快照,默认配置如下

save 900 1: 表示 在 900 秒内有1个或1个以上的键被修改就会进行快照处理。

save 300 10:表示 在 300 秒内有10个或10个以上的键被修改就会进行快照处理。

save 60 1000:表示在60秒内有1000个或1000个以上的键被修改就会进行快照处理。

2、用户在客户端直接SAVE或者BGSAVE命令。

3、如果用户为Redis设置了主从复制模式,从节点执行全量复制操作,则主节点会执行BGSAVE命令,将生产的RDB文件发送给从节点完成快照 操作。

4、如果用户自定义了快照条件,则在使用FLUSHALL命令清空数据库的过程中会触发一次快照。

RDB持久化实现

Redis fork()出一个子线程,并采用写时复制的策略,保证主线程与子线程数据的一致性,子线程将数据复制到新的RDB文件,并替换旧的RDB文件。

参考文献:高洪涛,刘河飞.从零开始学redis.北京:电子工业出版社,2019

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值