备注:测试版本 redis 4.0.9
Table of Contents
概述
redis是一个内存数据库,如果没有持久化功能,当redis重启、宕机、掉电等情况发生时,所有存储在内存中的数据就会丢失,这种情况在某些应用场景下是不允许发生的,例如:(1)将redis作为数据库使用时;(2)将redis作为缓存服务器,但缓存被穿透后会对性能造成较大影响,所有缓存同时失效会导致缓存雪崩,从而使服务无法响应。
这时我们希望redis能将数据从内存以某种形式同步到磁盘中,使得重启后可以根据硬盘中的记录恢复数据,这一过程就是持久化。redis支持RDB和AOF两种方式的持久化。前者会根据指定的规则定时将内存中的数据存储到磁盘上,后者在每次执行命令后将写数据的命令本身记录下来。两种持久化方式可以单独使用,也可同时使用。
一.RDB
1.1 RDB机制
RDB其实就是把数据以快照的形式保存在磁盘上。什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
RDB触发方式
命令 | 概述 |
---|---|
save触发方式 | 该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止 |
bgsave触发方式 | 执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。 |
配置文件自动触发 | save m n 表示m秒内数据集存在n次修改时,自动触发bgsave。 stop-writes-on-bgsave-error 默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。 rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。 rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。 dbfilename :设置快照的文件名,默认是 dump.rdb dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。 |
redis RDB配置文件
save和bgsave对比
1.2 RDB持久化测试
1.2.1 save备份
127.0.0.1:6379> save OK [root@10-31-1-123 redis]# ls -lrth 总用量 64K drwxr-xr-x. 2 root root 134 10月 30 14:10 bin -rw-r--r--. 1 root root 58K 11月 3 13:50 redis.conf -rw-r--r--. 1 root root 137 11月 3 13:52 dump.rdb [root@10-31-1-123 redis]# [root@10-31-1-123 redis]# pwd /usr/local/redis
复制
1.2.2 bgsave备份
-- 将上一个步骤的 备份文件重命名 [root@10-31-1-123 redis]# mv dump.rdb dump.rdb_20201103 [root@10-31-1-123 redis]# ls -lrth 总用量 64K drwxr-xr-x. 2 root root 134 10月 30 14:10 bin -rw-r--r--. 1 root root 58K 11月 3 13:50 redis.conf -rw-r--r--. 1 root root 137 11月 3 13:52 dump.rdb_20201103 127.0.0.1:6379> bgsave Background saving started 127.0.0.1:6379> [root@10-31-1-123 redis]# ls -lrth 总用量 68K drwxr-xr-x. 2 root root 134 10月 30 14:10 bin -rw-r--r--. 1 root root 58K 11月 3 13:50 redis.conf -rw-r--r--. 1 root root 137 11月 3 13:52 dump.rdb_20201103 -rw-r--r--. 1 root root 137 11月 3 13:56 dump.rdb [root@10-31-1-123 redis]#
复制
1.2.3 恢复测试
如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可
如果忘记了redis安装目录,可以运行如下命令查询
127.0.0.1:6379> config get dir 1) "dir" 2) "/usr/local/redis"
复制
恢复演练
-- 测试数据准备 127.0.0.1:6379> set my_db1 Oracle OK 127.0.0.1:6379> set my_db2 MySQl OK 127.0.0.1:6379> set my_db3 Redis OK -- 备份redis数据 127.0.0.1:6379> keys * 1) "my_db3" 2) "my_db2" 3) "my_db1" 127.0.0.1:6379> 127.0.0.1:6379> save OK -- 删除数据 127.0.0.1:6379> del my_db1 (integer) 1 127.0.0.1:6379> 127.0.0.1:6379> keys * 1) "my_db3" 2) "my_db2" -- 因为备份文件位置未发生变化,暂时不变化,直接重启redis redis-cli shutdown redis-server /usr/local/redis/redis.conf & -- 可以看到 被删除的my_db1已经被恢复了 [root@10-31-1-123 redis]# redis-cli 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> keys * 1) "my_db2" 2) "my_db3" 3) "my_db1"
复制
1.3 RDB优缺点
优点
(1)RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
(2)生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
(3)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点
RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据。
二.AOF
全量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。
2.1 AOF持久化原理及触发机制
如下图,有点类似关系型数据库的日志,把所有对数据的变更都记录起来
AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
AOF三种触发机制
命令 | 概述 |
---|---|
always | 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好 |
everysec | 异步操作,每秒记录 如果一秒内宕机,有数据丢失 |
no | 从不同步 |
2.2 AOF测试
2.2.1 开启AOF
-- 命令的方式 127.0.0.1:6379> config get appendonly 1) "appendonly" 2) "no" 127.0.0.1:6379> config set appendonly yes OK 127.0.0.1:6379> config get appendonly 1) "appendonly" 2) "yes" 127.0.0.1:6379> config rewrite OK 127.0.0.1:6379>
复制
当然,也可以通过修改配置文件的方式,区别在于修改配置文件需要重启redis服务,而通过config命令rewrite无需重启redis服务。
可以看到数据没有丢失,之前设置的3个key值都存在,都在aof文件中都有,这个算redis的一大改进。
之前版本,同时存在AOF和RDB的情况下,redis重启的时候只会读取AOF,而AOF刚开启的时候,不包含已存在的key值,会导致之前的key值丢失。
[root@10-31-1-123 redis]# more appendonly.aof *2 $6 SELECT $1 0 *3 $3 SET $6 my_db2 $5 mysql *3 $3 SET $6 my_db3 $5 redis *3 $3 SET $6 my_db1 $6 Oracle
复制
2.3 AOF优缺点
优点
(1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
(2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
(4)AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据
缺点
(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大
(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的
(3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。
参考
1.https://blog.csdn.net/wzy0623/article/details/82464270
2.https://baijiahao.baidu.com/s?id=1654694618189745916