RDB和AOF的持久化配置和相关数据恢复实验

需求

  • RDB的持久化配置和相关的数据恢复实验
  • AOF的持久化配置和相关的数据恢复实验

RDB的持久化配置和相关的数据恢复实验

  • 配置.

1.登录redis服务器,进入redis安装目录:

cd /usr/local/redis-3.2.8
vi redis.conf  

2.找到如下的信息:

save 900 1
save 300 10
save 60 10000

命令 save 300 10的含义是每隔300s,如果有超过10个key发生了变更,那么就生成一个新的dump.rdb文件,就是当前redis内存中完整的数据快照,这个操作也被称之为snapshotting,快照。
也可以手动调用save或者bgsave命令,同步或异步执行rdb快照生成。
save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去check一下,是否有指定的key数量发生了变更,如果有,就生成一个新的dump.rdb文件。
注意:dump.rdb,每次生成一个新的快照,都会覆盖之前的老快照。

3.在上方配置文件的信息处,重新添加一个检查点,保存退出,信息如下:

save 10 1

4.RDB文件备份过程:

1. redis根据配置自己尝试去生成rdb快照文件。

2. fork一个子进程出来。

3.子进程尝试将数据dump到临时的rdb快照文件中。

4. 完成rdb快照文件的生成之后,就替换之前的旧的快照文件。

  • 实验.

1.启动redis服务。

cd /usr/local/redis-3.2.8/src 
./redis-server ../redis.conf 

2.查看对应的redis服务是否已经启动:

[root@eshop-cache01 src]# ps -ef|grep redis
root      1325     1  0 06:50 ?        00:00:00 ./redis-server 127.0.0.1:6379
root      1338  1191  0 06:51 pts/0    00:00:00 grep redis

3.登录redis,set几个值:

[root@eshop-cache01 src]# ./redis-cli 
127.0.0.1:6379> get all
(nil)
127.0.0.1:6379> set key1 val1
OK
127.0.0.1:6379> set key2 val2
OK
127.0.0.1:6379> set key2 val2

4.迅速 kill-9 掉对应的redis服务的进程1325:

 kill -9 1325 

5.查看对应的redis服务是否已经停止,如下信息就代表已经停止:

[root@eshop-cache01 run]# ps -ef|grep redis
root      1375  1191  0 07:12 pts/0    00:00:00 grep redis

6.删除对应的redis的pid文件(不是正常停止的,pid文件依然存在,重新启动会报错):

[root@eshop-cache01 run]# pwd
/var/run
[root@eshop-cache01 run]# rm redis_6379.pid
rm: remove regular file `redis_6379.pid'? yes
[root@eshop-cache01 run]# 

7.重新启动redis服务,登录对应服务,发现之前设置的redis的值,已经不存在:

[root@eshop-cache01 src]# ./redis-server ../redis.conf 
[root@eshop-cache01 src]# ps -ef|grep redis
root      1387     1  0 07:53 ?        00:00:00 ./redis-server 127.0.0.1:6379
root      1391  1303  0 07:53 pts/1    00:00:00 grep redis
[root@eshop-cache01 src]# ./redis-cli 
127.0.0.1:6379> get key1
(nil)
127.0.0.1:6379> get key2
(nil)
127.0.0.1:6379> 

8.重新往redis中设置几个值,并用命令shutdown调对应的redis服务:

127.0.0.1:6379> set key1 val
OK
127.0.0.1:6379> set key2 va2
OK
127.0.0.1:6379> shutdown
not connected> 

9.重新启动redis服务,查看对应的数据依然存在:

[root@eshop-cache01 src]# ./redis-server  ../redis.conf 
[root@eshop-cache01 src]# ps -ef |grep redis
root      1415     1  0 08:04 ?        00:00:00 ./redis-server 127.0.0.1:6379
root      1419  1191  0 08:04 pts/0    00:00:00 grep redis
[root@eshop-cache01 src]# ./redis-cli 
127.0.0.1:6379> get key1
"val"
127.0.0.1:6379> get key2
"va2"
127.0.0.1:6379> 
  • 结论.
    1.redis突然出现服务异常(比如直接kill-9)时,RDB持久化方式会导致设置的检查点内的数据丢失。
    2.redis的shutdown命令,是一个安全的退出redis的方式。

AOF的持久化配置和相关的数据恢复实验

  • 配置.

1.登录redis服务器,进入redis安装目录:

cd /usr/local/redis-3.2.8
vi redis.conf  

2.找到如下的信息:

appendonly no

3.将配置修改为如下内容,保存退出:

appendonly yes

注意AOF日志redis默认是关闭的,必须要通过配置打开。打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下。而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整。

4.AOF的三种fsync策略:

(1).always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了。

(2). everysec: 每秒将os cache中的数据fsync到磁盘,这个最常用的,生产环境一般都这么配置,性能很高,QPS还是可以上万的,redis默认启用的是此种策略。

(3). no: 仅仅redis负责将数据写入os cache就撒手不管了,然后后面os自己会时不时有自己的策略将数据刷入磁盘,不可控了。

  • 实验.

通过第一个RDB的数据实验,我们知道,仅仅只有RDB数据的时候,往redis中设入值后,再kill -9掉对应的redis服务,容易导致数据的丢失。现在我们启用AOF日志策略后,再进行相同的操作,看看对应数据是否会丢失。

1.登录redis服务器,进入redis安装目录:

cd /usr/local/redis-3.2.8/src
[root@eshop-cache01 src]# ./redis-server ../redis.conf 
[root@eshop-cache01 src]# ps -ef|grep redis
root      1437  1191  0 09:38 pts/0    00:00:00 vi ../redis.conf
root      1456     1  0 10:03 ?        00:00:00 ./redis-server 127.0.0.1:6379
root      1460  1303  0 10:04 pts/1    00:00:00 grep redis
[root@eshop-cache01 src]# ./redis-cli 
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set key1 val1
OK
127.0.0.1:6379> set key2 val2
OK
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
127.0.0.1:6379> 

2.立刻杀死redis对应的进程:

[root@eshop-cache01 src]# kill -9 1456
[root@eshop-cache01 src]# ps -ef|grep redis
root      1462  1303  0 10:05 pts/1    00:00:00 ./redis-cli
root      1466  1191  0 10:09 pts/0    00:00:00 grep redis
[root@eshop-cache01 src]# 

3.删除对应的redis的pid文件(不是正常停止的,pid文件依然存在,重新启动会报错):

[root@eshop-cache01 run]# pwd
/var/run
[root@eshop-cache01 run]# rm redis_6379.pid
rm: remove regular file `redis_6379.pid'? yes
[root@eshop-cache01 run]# 

4.重新启动redis服务,登录对应服务,发现之前设置的redis的值,依然存在:

[root@eshop-cache01 src]# ./redis-server ../redis.conf 
[root@eshop-cache01 src]# ps -ef|grep redis
root      1471     1  0 10:11 ?        00:00:00 ./redis-server 127.0.0.1:6379
root      1476  1303  0 10:11 pts/1    00:00:00 grep redis
[root@eshop-cache01 src]# ./redis-cli 
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
127.0.0.1:6379> 

注意:其实你在appendonly.aof文件中,可以看到刚写的日志,它们以指令的形式存放在aof文件中,可以直接打开查看,所以这也表明aof文件是一个指令文件,不是rdb的数据快照。而且文件中的数据其实就是先写入os cache的,然后1秒后才fsync到磁盘中,只有fsync到磁盘中了,才是安全的,要不然光是在os cache中,机器只要重启,就什么都没了。kill -9杀掉redis进程,重新启动redis进程,发现数据被恢复回来了,就是从AOF文件中恢复回来的。记住,即便是配置了everysec策略,也不能完全保证数据不丢失,依然会丢失1s的数据。想要数据不丢失,只能够设置always策略,但是生产环境不建议如此,性能太差。

  • AOF rewrite说明

1.redis中的数据其实有限的,很多数据可能会自动过期,可能会被用户删除,可能会被redis用缓存清除的算法清理掉。

redis中的数据会不断淘汰掉旧的,就一部分常用的数据会被自动保留在redis内存中。所以可能很多之前的已经被清理掉的数据,对应的写日志还停留在AOF中,AOF日志文件就一个,会不断的膨胀,到很大很大。

所以AOF会自动在后台每隔一定时间做rewrite操作,比如日志里已经存放了针对100w数据的写日志了; redis内存只剩下10万; 基于内存中当前的10万数据构建一套最新的日志,到AOF中; 覆盖之前的老日志; 确保AOF日志文件不会过大,保持跟redis内存数据量一致。

2.redis 2.4之前,还需要手动,开发一些脚本,crontab,通过BGREWRITEAOF命令去执行AOF rewrite,但是redis 2.4之后,会自动进行rewrite操作。

3.在redis.conf中,可以配置rewrite策略:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

上面配置的说明

比如说上一次AOF rewrite之后,是128mb。然后就会接着128mb继续写AOF的日志,如果发现增长的比例,超过了之前的100%,256mb,就可能会去触发一次rewrite。但是此时还要去跟min-size,64mb去比较,256mb > 64mb,才会去触发rewrite。

4.aof日志的过程

  • redis fork一个子进程。
  • 子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志。
  • redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件。
  • 子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中。
  • 用新的日志文件替换掉旧的日志文件。

所以,aof文件始终只有一个。

RDB和AOF同时工作

  • 如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting。

  • 如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite。

  • 同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整。

对于以上三点,可以简单的做个小实验,就是同时开启rdb和aof,然后设置一些值后,关闭redis,清空对应的aof文件中的指令,然后再启动redis,发现rdb文件中虽然存在数据,但是redis内存中已经不存在数据了。具体的演示我就不做了,想要验证的可以试试看。

你可能感兴趣的:(RDB和AOF的持久化配置和相关数据恢复实验)