写点什么

一文搞明白 Redis 中两种持久化机制 RDB 和 AOF

作者:jiangxl
  • 2022 年 4 月 29 日
  • 本文字数:4024 字

    阅读完需:约 13 分钟

一文搞明白Redis中两种持久化机制RDB和AOF

redis 两种持久化类型

1.redis 两种持久化操作

redis 支持两种方式的持久化,一种是 RDB 方式,一种是 AOF 方式,这两种方式可以单独使用其中一种,也可以混合使用


如果不使用持久化,那么当 redis 重启后,所有的数据会全部消失


redis 重启前是有很多 key 的



当 redis 重启后,所有 key 全部消失


1.1.RDB 方式

RDB 方式就类似于快照,当符合一定条件的数据,Redis 会自动将内存中的所有数据打一个快照,并存储到磁盘上,主要有两个参数构成,时间和改动,比如在 1 分钟内如果产生了 1000 个 key,那么就打一个快照,RDB 是 redis 的默认持久化方式


redis 启动后会读取 RDB 快照文件,将数据从硬盘载入到内存,一般情况下 1G 的快照文件载入到内存的时间大约是 20-30s


RDB 持久化优缺点:


可以在指定的时间间隔内生成数据集的时间点快照


优点:速度快,适合用作备份,主从复制也是基于 RDB 持久化功能实现的


缺点:会有数据丢失


RDB 持久化原理:


1.当 rdb 条件满足时,redis 会调用系统函数 fork(),创建一个子进程进行持久化


2.子进程将数据集写入到一个临时的 rdb 文件中,当子进程完成对临时 rdb 文件的写入时,redis 用新的 rdb 文件替换原来旧的 rdb 文件,并将旧的 rdb 文件删除


在执行 fork 的时候操作系统会使用写时复制策略,即函数发送的一刻,父子进程共享同一个内存数据,当父进程要更改其中某片数据时,操作系统会将该片数据复制一份以保证子进程的数据不受影响,所以新的 rdb 文件存储的是执行 for 那一刻的内存数据


Redis 在进行快照的过程中不会修改 RDB 文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候 RDB 文件都是完整的。这使得我们可以通过定时备份 RDB 文件来实 现 Redis 数据库备份。RDB 文件是经过压缩(可以配置 rdbcompression 参数以禁用压缩节省 CPU 占用)的二进制格式,所以占用的空间会小于内存中的数据大小,更加利于传输


除了自动快照,还可以手动发送 SAVE 或 BGSAVE 命令让 Redis 执行快照,两个命令的区别在于,前者是由主进程进行快照操作,会阻塞住其他请求,后者会通过 fork 子进程进行快照操作。

1.2.AOF 方式

AOF 会记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集


AOF 的特点就是记录服务器运行过程中产生的所有命令,如果有 del 命令,当 aof 文件的大小达到限制时,会触发内部的一个压缩命令,将 del 命令删除以及 del 之前创建的 key 一并从文件中删除,当服务器再次启动时,重新执行这些命令来还原数据


AOF 文件中的命令全部以 redis 协议的格式来保存,新命令会被追加到文件的末尾


优点:可以最大程度保证数据不丢失


缺点:日志记录量级比较大


RDB 持久化有时候不生效,生成环境中建议使用 AOF 来做持久化,两者也可以并存

2.redis 持久化配置操作

2.1.RDB 持久化操作

RDB 持久化不是实时保存 redis 数据的,也是需要一个过程

2.1.1.配置 RDB 持久化

注意:redis 配置文件不能在参数后面加任何注释,否则会不生效


1.配置rdb持久化[root@redis-1 ~]# vim /data/redis_cluster/redis_6379/conf/redis_6379.conf dbfilename redis_6379.rdb        #指定本地持久化文件的文件名,默认dump.rdbdir /data/redis_cluster/redis_6379/data    #本地数据库的目录,rdb文件路径save 900 1              //900秒(15分钟)内有1个更改save 300 100            //300秒(5分钟)内有100个更改save 60 10000           //60秒(1分钟)内有10000个更改
2.重启redis[root@redis-1 ~]# redis-cli 127.0.0.1:6379> shutdown[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
复制代码

2.1.2.批量创建 key 并观察 rdb 文件是否创建

批量创建key[root@redis-1 ~]# for i in {1..15000}doredis-cli set k_${i} v_${i}echo "k_${i} is ok"

观察rdb文件是否产生[root@redis-1 ~]# ll /data/redis_cluster/redis_6379/data/redis_6379.rdb -rw-r--r--. 1 root root 148006 1月 28 14:39 /data/redis_cluster/redis_6379/data/redis_6379.rdb
复制代码

2.1.3.关闭 redis 验证持久化是否生效

1.查看key并关闭redis,关闭redis的时候一定要大于缓存设定的数据,否则会不生效,[root@redis-1 ~]# redis-cli 127.0.0.1:6379> DBSIZE(integer) 15000127.0.0.1:6379> 127.0.0.1:6379> shutdown
2.再次启动redis查看key,数据还是存在的[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf [root@redis-1 ~]# redis-cli dbsize(integer) 16000
3.rdb有时会生成不了持久化文件,我们可以使用bgsave命令手动持久化[root@redis-1 ~]# redis-cli 127.0.0.1:6379> BGSAVEBackground saving started127.0.0.1:6379> SHUTDOWNnot connected> exit.再次启动redis查看数据有没有丢失[root@redis-1 ~]# redis-cli 127.0.0.1:6379> DBSIZE(integer) 16000
复制代码

2.2.AOF 持久化操作

2.2.1.配置 AOF 持久化

注意:配置 AOF 时不能有注释存在


1.配置aof[root@redis-1 ~]# vim /data/redis_cluster/redis_6379/conf/redis_6379.conf dir /data/redis_cluster/redis_6379/data/    //持久化文件路径appendonly yes                  //是否打开aof日志功能appendfilename "appendonly.aof"          //aof文件名称appendfsync always                      //每执行一个命令都立即同步到aof持久化文件appendfsync everysec                    //每秒写入1次appendfsync no                          //写入功能交给操作系统,由操作系统判断缓冲区大小,统一写到aofno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb           //aof文件大小,当超过设定的值就执行aof压缩命令aof-load-truncated yes
2.启动redis
复制代码

2.2.批量创建 key 并观察 aof 文件变化

1.批量生产key[root@redis-1 ~]# for i in {1..15000}doredis-cli set k_${i} v_${i}echo "k_${i} is ok"done
2.观察aof文件的,会持续增长,redis每执行一个命令都会记录到aof中[root@redis-1 ~]# cd /data/redis_cluster/redis_6379/data[root@redis-1 /data/redis_cluster/redis_6379/data]# ll appendonly.aof -rw-r--r--. 1 root root 257031 1月 28 14:02 appendonly.aof[root@redis-1 /data/redis_cluster/redis_6379/data]# ll appendonly.aof -rw-r--r--. 1 root root 266836 1月 28 14:02 appendonly.aof[root@redis-1 /data/redis_cluster/redis_6379/data]# ll appendonly.aof -rw-r--r--. 1 root root 272571 1月 28 14:02 appendonly.aof[root@redis-1 /data/redis_cluster/redis_6379/data]# ll appendonly.aof -rw-r--r--. 1 root root 277566 1月 28 14:02 appendonly.aof
复制代码

2.2.3.重启 redis 查看数据是否会丢失

1.关闭redis[root@redis-1 ~]# redis-cli 127.0.0.1:6379> SHUTDOWN 
2.启动redis[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf
3.查看数据是否丢失,还是15000个key,数据全部都在[root@redis-1 ~]# redis-cli 127.0.0.1:6379> DBSIZE(integer) 15000
复制代码

2.2.4.观察 aof 持久化文件

aof 文件会记录 redis 的所有更改命令


删除、新增 key 都会记录在 aof 文件中,当 redis 重启后,会将 aof 文件中的命令还原到 redis 中,从而保证数据的持久化,我们配置的 aof 文件大小为 64m,默认就是 64m,当文件超过 64m 时,redis 有自己的压缩策略,会把 aof 中的删除命令全部删掉,保证文件的大小,也可以根据实际生产把文件大小给大


3.redis 持久化隐藏技能

3.1.redis 支持热更新配置

redis 中某些配置也是支持热更新的,只需要在命令行执行命令即可加载配置


查看配置:config get *


配置参数:config set 配置


查看当前redis的所有配置127.0.0.1:6379> CONFIG GET *  1) "dbfilename"  2) "redis_6379.rdb"  3) "requirepass"  4) ""  5) "masterauth"  6) ""  7) "unixsocket"  8) ""  9) "logfile" 10) "/data/redis_cluster/redis_6379/logs/redis_6379.log" 11) "pidfile"··························
查看redis的rdb配置127.0.0.1:6379> CONFIG GET save1) "save"2) "900 1 300 100 60 10000"
rdb配置时支持热更新的1.将rdb的配置取消127.0.0.1:6379> CONFIG SET save ""OK127.0.0.1:6379> CONFIG GET save 1) "save"2) ""
2.配置rdb127.0.0.1:6379> CONFIG SET save "60 10000 300 100 900 1"OK127.0.0.1:6379> CONFIG GET save 1) "save"2) "60 10000 300 100 900 1"
复制代码

3.2.rdb 和 aof 同时使用

结论:rdb 和 aof 同时存在,redis 每次启动读取的是 aof 持久化文件而不是 rdb 持久化文件


1.将rdb文件清空[root@redis-1 ~]# > /data/redis_cluster/redis_6379/data/redis_6379.rdb 2.重启redis[root@redis-1 ~]# redis-cli shutdown[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf 3.redis还是有数据的[root@redis-1 ~]# redis-cli dbsize(integer) 16000

1.将aof文件清空,rdb文件保存[root@redis-1 ~]# ll /data/redis_cluster/redis_6379/data/redis_6379.rdb -rw-r--r--. 1 root root 249870 1月 28 14:53 /data/redis_cluster/redis_6379/data/redis_6379.rdb[root@redis-1 ~]# > /data/redis_cluster/redis_6379/data/appendonly.aof [root@redis-1 ~]# ll /data/redis_cluster/redis_6379/data/appendonly.aof-rw-r--r--. 1 root root 0 1月 28 14:53 /data/redis_cluster/redis_6379/data/appendonly.aof2.重启redis[root@redis-1 ~]# redis-cli shutdown[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6379/conf/redis_6379.conf 3.查看数据发现已经清空[root@redis-1 ~]# redis-cli dbsize(integer) 0
复制代码

3.3.redis shutdown 命令

redis 配置了 rdb 持久化之后,使用 shutdown 关闭 redis 时,系统首先执行 bgsave,将数据保存到持久化文件,再执行 shutdown,这样就做到了数据的持久化

发布于: 2022 年 04 月 29 日阅读数: 67
用户头像

jiangxl

关注

CSDN、阿里云、华为云、51CTO等博客专家 2022.04.27 加入

CSDN博客专家、51CTO专家博主、阿里云博客专家、华为云享专家、DevOps运维领域优质创作者,擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、大规模互联网WEB集群架构

评论

发布
暂无评论
一文搞明白Redis中两种持久化机制RDB和AOF_redis'_jiangxl_InfoQ写作社区