Linux 持久化之AOF操作【redis】

前言✍

可以先看往期的 【RDB🔍】
快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、以及未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

什么是AOF
AOF,英文是Append Only File,即只允许追加不允许改写的文件(修改aof会导致错误需要恢复,重启)

在这里插入图片描述

如果要使用AOF,需要修改配置文件:
appendonly no yes则表示启用AOF
默认是不开启的,我们需要手动配置,然后重启redis,就可以生效了!
将我们的命令都记录下来,history,恢复的时候就把文件全部执行一遍!

👇来着(配置文件redis.conf)
在这里插入图片描述
除了这些还有

#appendfsync always # 每次修改都会sync,消耗性能
#appendfsync everysec # 每秒执行一次sync,可能丢失这1s数据!
#appendfsync  no   #不执行sync,这个时候操作系统自己同步数据,速度最快!
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
 # aof默认就是文件的无限追加,越来越大
 # 如果aof文件大于64mb
 #frok一个新的的进程来将我们的文件进行重写!

appendonly

appendonly默认是不开启的,需要手动进行配置
在这里插入图片描述

1.首先开启两个会话👇
在这里插入图片描述
连接会话1 20001107
2.打开redis.conf把的no改为yes就可以了(开启aof)
这时我们还没有重启redis
我们看到bin目录下没有aof文件

[root@GongQlLong bin]# ls
dump.rdb    
redis-benchmark  
redis-check-rdb  redis.conf      
redis-server
gongconfig  
redis-check-aof  
redis-cli        
redis-sentinel

删除dump.rdb文件

[root@GongQlLong bin]# ls
dump.rdb    
redis-benchmark  
redis-check-rdb  
redis.conf     
redis-server
gongconfig  
redis-check-aof  
redis-cli        
redis-sentinel
[root@GongQlLong bin]# rm -rf dump.rdb 

连接会话2 20001107
3.重启redis

[root@GongQlLong bin]# redis-server gongconfig/redis.conf 
27564:C 05 Dec 2021 16:44:50.933 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
27564:C 05 Dec 2021 16:44:50.933 # Redis version=5.0.14, bits=64, commit=00000000, modified=0, pid=27564, just started
27564:C 05 Dec 2021 16:44:50.933 # Configuration loaded
[root@GongQlLong bin]# redis-cli
127.0.0.1:6379> ping
OK

连接会话1 20001107

4.查看bin目录

[root@GongQlLong bin]# ls
appendonly.aof  
gongconfig       
redis-check-aof  
redis-cli   
redis-sentinel
dump.rdb        
redis-benchmark  
redis-check-rdb  
redis.conf  
redis

出现了appendonly.aof也有了dump.rdb
Aof保存的是appendonly.aof文件

AOF命令同步

AOF 命令同步
Redis 将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件, 以此达到记录数据库状态的目的, 为了方便起见, 我们称呼这种记录过程为同步。

举个例子, 如果执行以下命令:

redis> RPUSH list 1 2 3 4
(integer) 4

redis> LRANGE list 0 -1
1) "1"
2) "2"
3) "3"
4) "4"

redis> KEYS *
1) "list"

redis> RPOP list
"4"

redis> LPOP list
"1"

redis> LPUSH list 1
(integer) 3


redis> LRANGE list 0 -1
1) "1"
2) "2"
3) "3"

那么其中四条对数据库有修改的写入命令就会被同步到 AOF 文件中:

RPUSH list 1 2 3 4

RPOP list

LPOP list

LPUSH list 1

为了处理的方便, AOF 文件使用网络通讯协议的格式来保存这些命令。

比如说, 上面列举的四个命令在 AOF 文件中就实际保存如下:

*2
$6
SELECT
$1
0
*6
$5
RPUSH
$4
list
$1
1
$1
2
$1
3
$1
4
*2
$4
RPOP
$4
list
*2
$4
LPOP
$4
list
*3
$5
LPUSH
$4
list
$1
1

如果这个aof文件有错位(比如你打开这个文件
(vim appendonly.aof然后修改保存过的值)比如上面保存过的aof文件,把它修改一下

*2
$6
SELECT
$1
0
*6
$5
RPUSH
$4
list
$1
1
$1
2
$1
3
$1
4
*2
$4
RPOP
$4
list
*2
$4
LPOP
$4
list
*3
$5
LPUSH
$4
list
$1
adsddsadad sadas # 这是修改后的

这时候redis是启动不起来的,想要运行起来redis,需要修改这个恢复文件!!!!

恢复文件

redis给我们提供了一个工具redis-check-aof --fix

AOF 后台重写

AOF 重写程序可以很好地完成创建一个新 AOF 文件的任务, 但是, 在执行这个程序的时候, 调用者线程会被阻塞。
很明显, 作为一种辅佐性的维护手段, Redis 不希望 AOF 重写造成服务器无法处理请求, 所以 Redis 决定将 AOF 重写程序放到(后台)子进程里执行, 这样处理的最大好处是:

  1. 子进程进行 AOF 重写期间,主进程可以继续处理命令请求。
  2. 子进程带有主进程的数据副本,使用子进程而不是线程,可以在避免锁的情况下,保证数据的安全性。

不过, 使用子进程也有一个问题需要解决: 因为子进程在进行 AOF 重写期间, 主进程还需要继续处理命令, 而新的命令可能对现有的数据进行修改, 这会让当前数据库的数据和重写后的 AOF 文件中的数据不一致。

为了解决这个问题, Redis 增加了一个 AOF 重写缓存, 这个缓存在 fork 出子进程之后开始启用, Redis 主进程在接到新的写命令之后, 除了会将这个写命令的协议内容追加到现有的 AOF 文件之外, 还会追加到这个缓存中:
在这里插入图片描述

换言之, 当子进程在执行 AOF 重写时, 主进程需要执行以下三个工作:

处理命令请求。
将写命令追加到现有的 AOF 文件中。
将写命令追加到 AOF 重写缓存中。
这样一来可以保证:

现有的 AOF 功能会继续执行,即使在 AOF 重写期间发生停机,也不会有任何数据丢失。
所有对数据库进行修改的命令都会被记录到 AOF 重写缓存中。
当子进程完成 AOF 重写之后, 它会向父进程发送一个完成信号, 父进程在接到完成信号之后, 会调用一个信号处理函数, 并完成以下工作:

将 AOF 重写缓存中的内容全部写入到新 AOF 文件中。
对新的 AOF 文件进行改名,覆盖原有的 AOF 文件。
当步骤 1 执行完毕之后, 现有 AOF 文件、新 AOF 文件和数据库三者的状态就完全一致了。

当步骤 2 执行完毕之后, 程序就完成了新旧两个 AOF 文件的交替。

这个信号处理函数执行完毕之后, 主进程就可以继续像往常一样接受命令请求了。 在整个 AOF 后台重写过程中, 只有最后的写入缓存和改名操作会造成主进程阻塞, 在其他时候, AOF 后台重写都不会对主进程造成阻塞, 这将 AOF 重写对性能造成的影响降到了最低。
以上就是 AOF 后台重写

优点

  • 每一次修改都同步,文件的完整会更加好!
  • 每秒同步一次,可能会丢失一秒的数据
  • 从不同步,效率最高的

缺点

  • 相对于数据文件来说,aof远远大于rdb,修改的速度也比rdb慢
  • Aof运行速率也要比rdb慢,说一我们redis默认的配置就是rdb持久化

扩展与总结

  1. AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就这么简单。

  2. 我们通过配置redis.conf中的appendonly yes就可以打开AOF功能。如果有写操作(如SET等),redis就会被追加到AOF文件的末尾。

  3. 默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。

  4. 如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。

  5. 因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。

  6. 在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性

  7. AOF方式的另一个好处,我们通过一个“场景再现”来说明。某同学在操作redis时,不小心执行了FLUSHALL,导致redis内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了。是不是很神奇,这就是AOF持久化方式的好处之一。但是如果AOF文件已经被重写了,那就无法通过这种方法来恢复数据了。

  8. 虽然优点多多,但AOF方式也同样存在缺陷,比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。

  9. 如果你直接执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最少的命令集。

  10. 如果运气比较差,AOF文件出现了被写坏的情况,也不必过分担忧,redis并不会贸然加载这个有问题的AOF文件,而是报错退出。这时可以通过以下步骤来修复出错的文件:

  • 备份被写坏的AOF文件
  • 运行redis-check-aof –fix进行修复
  • 用diff -u来看下两个文件的差异,确认问题点
  • 重启redis,加载修复后的AOF文件
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪哇贡尘拾Miraitow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值