redis 通过aof日志恢复_基于Redis的AOF持久化及数据恢复

AOF持久化配置

AOF持久化默认是关闭的;默认打开的是RDB的持久化。

生产环境里面AOF都是要打开的

appendonly yes

# appendfsync always

appendfsync everysec

# appendfsync no

打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中:先写入os cache的,然后每隔一定时间再fsync一下;

而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整。

AOF的fsync策略有三种可以选择:

每次写入一条数据就执行一次fsync;

每隔一秒执行一次fsync;

一种是不主动执行fsync。

always: 每写入一条数据立即写日志fsync到磁盘上去,性能非常非常差,吞吐量很低;

everysec: 每秒将os cache中的数据fsync到磁盘,性能很高,QPS还是可以上万的;

no: 仅负责将数据写入os cache,os根据自己的策略将数据刷入磁盘。

mysql和redis对比(QPS):

mysql内存策略:大量磁盘,QPS到一两千;

redis基于内存: 磁盘持久化,QPS到多少上万。

AOF持久化数据恢复

修改配置:打开AOF的开关

appendonly yes

重启

redis-cli SHUTDOWN

./redis_6379 start

写入一些数据,观察AOF文件中的日志内容

root@VM-0-10-ubuntu:/etc/init.d# redis-cli

127.0.0.1:6379> set myhello aaa

OK

ls /var/redis/6379/

appendonly.aof dump.rdb

root@VM-0-10-ubuntu:/etc/init.d# cat /var/redis/6379/appendonly.aof

*2

$6

SELECT

$1

0

*3

$3

set

$7

myhello

$3

aaa

在appendonly.aof文件中,可以看到刚写的日志。其实是先写入os cache的,然后1秒后才fsync到磁盘中。

-kill -9杀掉redis进程,重新启动redis进程

root@VM-0-10-ubuntu:/etc/init.d# ps -ef|grep redis

root 10302 1 0 18:34 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379

root 11164 8229 0 18:40 pts/0 00:00:00 grep --color=auto redis

root@VM-0-10-ubuntu:/etc/init.d# kill -9 10302

root@VM-0-10-ubuntu:/etc/init.d# ./redis_6379 start

/var/run/redis_6379.pid exists, process is already running or crashed

root@VM-0-10-ubuntu:/etc/init.d# rm -rf /var/run/redis_6379.pid

root@VM-0-10-ubuntu:/etc/init.d# ./redis_6379 start

root@VM-0-10-ubuntu:/etc/init.d# redis-cli

127.0.0.1:6379> get myhello

"aaa"

127.0.0.1:6379> get k1

(nil)

发现数据被恢复了,但是之前保存在RDB里的数据没有了。

这也说明了redis启动的时候,直接从appendonly.aof中加载所有的日志来恢复数据。

AOF rewrite

redis中的数据其实有限的,很多数据可能会自动过期。

AOF会自动在后台每隔一定时间做rewrite操作, 确保AOF日志文件不会过大,保持跟redis内存数据量一致。目前redis会自动进行rewrite操作。

通过在redis.conf中配置rewrite策略:

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

比如说上一次AOF rewrite 是100mb,然后就会接着100mb继续写AOF的日志,如果发现增长的比例,超过了之前的100% 也就是200mb,就可能会去触发一次rewrite;

但是此时还要去跟min-size,64mb去比较,200mb > 64mb,才会去触发rewrite。

fork子进程,基于当前内存中的数据,往一个新的临时的AOF文件中写入日志;

redis主进程在接收到新的写操作之后,在内存中写入日志,同时也继续写入旧的AOF文件

子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中

用新的日志文件替换掉旧的日志文件

AOF破损文件的修复

如果redis在append数据到AOF文件时,机器宕机会导致AOF文件损坏。如将appendonly.aof删掉最后一行来模拟宕机:

root@VM-0-10-ubuntu:~# vi /var/redis/6379/appendonly.aof

*2

$6

SELECT

$1

0

*3

$3

set

$7

myhello

$3

用redis-check-aof --fix命令来修复AOF文件:

root@VM-0-10-ubuntu:~/redis/redis-4.0.9/src# ./redis-check-aof --fix /var/redis/6379/appendonly.aof

0x 35: Expected to read 5 bytes, got 0 bytes

AOF analyzed: size=53, ok_up_to=23, diff=30

This will shrink the AOF from 53 bytes, with 30 bytes, to 23 bytes

Continue? [y/N]: y

Successfully truncated AOF

cat /var/redis/6379/appendonly.aof

*2

$6

SELECT

$1

0

AOF和RDB同时工作

1.如果RDB执行snapshotting,那么redis就不会再去执行AOF rewrite。反之,如果redis在执行AOF rewrite,那么也不会执行RDB snapshotting;

2.如果RDB执行snapshotting,此时用户也在执行BGREWRITEAOF命令,那么只有等RDB快照生成之后,才会执行AOF rewrite;

3.如果同时拥有RDB snapshot文件和AOF日志文件,那么redis重启的时候会优先使用AOF进行恢复,因为其日志更完整。

总结

同时有rdb的dump和aof的appendonly,优先使用AOF进行恢复,rdb的数据不会恢复到内存中

模拟aof破损,然后通过命令fix,破损的数据会被删除

数据恢复完全依赖于磁盘持久化,如果rdb和aof上都没有数据,数据就无法恢复了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值